Macos 模拟系统范围热键的按键
我需要在OSX中模拟击键。我是这样做的:Macos 模拟系统范围热键的按键,macos,cocoa,Macos,Cocoa,我需要在OSX中模拟击键。我是这样做的: -(void)execute { CGEventSourceRef sourceRef = CGEventSourceCreate(kCGEventSourceStateHIDSystemState); CGEventRef keyPress = CGEventCreateKeyboardEvent (sourceRef, (CGKeyCode)keyCode, true); CGEventRef keyUnpress
-(void)execute {
CGEventSourceRef sourceRef =
CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
CGEventRef keyPress = CGEventCreateKeyboardEvent (sourceRef, (CGKeyCode)keyCode, true);
CGEventRef keyUnpress = CGEventCreateKeyboardEvent (sourceRef, (CGKeyCode)keyCode, false);
CGEventSetFlags(keyPress, modifierFlags);
CGEventPost(kCGHIDEventTap, keyPress);
//unpressing the acualkey
CGEventPost(kCGHIDEventTap, keyUnpress);
CFRelease(keyPress);
CFRelease(keyUnpress);
CFRelease(sourceRef);
}
它适用于任何应用程序中的每个热键或简单按键,但不适用于系统范围的快捷方式,例如option+space启动Spotlight或cmd+shift+4制作屏幕截图或ctrl+`打开iTerm2窗口
我试图更改事件的来源和发布事件的位置,但没有帮助。有什么想法吗?来自CGEventCreateKeyboardEvent的文档: 必须输入生成角色所需的所有击键,包括修改键。例如,要生成“Z”,SHIFT键必须向下,“Z”键必须向下,然后必须释放SHIFT键和“Z”键: 所以,你不能仅仅用选项修改器按下并释放空格来触发一个选项空格;您必须按option,按空格,释放空格,释放选项 作为旁注,optspace在默认情况下不做任何事情;cmd space是聚光灯搜索热键,cmd opt space是聚光灯窗口热键 因此,此代码将弹出聚光灯搜索:
- (void)execute {
CGEventSourceRef src =
CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
CGEventRef cmdd = CGEventCreateKeyboardEvent(src, 0x38, true);
CGEventRef cmdu = CGEventCreateKeyboardEvent(src, 0x38, false);
CGEventRef spcd = CGEventCreateKeyboardEvent(src, 0x31, true);
CGEventRef spcu = CGEventCreateKeyboardEvent(src, 0x31, false);
CGEventSetFlags(spcd, kCGEventFlagMaskCommand);
CGEventSetFlags(spcu, kCGEventFlagMaskCommand);
CGEventTapLocation loc = kCGHIDEventTap; // kCGSessionEventTap also works
CGEventPost(loc, cmdd);
CGEventPost(loc, spcd);
CGEventPost(loc, spcu);
CGEventPost(loc, cmdu);
CFRelease(cmdd);
CFRelease(cmdu);
CFRelease(spcd);
CFRelease(spcu);
CFRelease(src);
}
作为记录,@abarnert的答案很好,根据文档,这是您应该使用的方法,但我的原始代码也可以使用。我发现我有一个与这个问题无关的问题
因此,如果需要将修改器键应用于按键,只需像下面这样添加它们
CGEventSetFlags(keypress,modifierFlags)代码>无需单独按下每个修改器键。这种方法很有效,我还没有发现任何缺点,代码的可读性要好得多。对于其他想要CGKeyCode列表的人,这里有一个带有部分表的函数
虽然这可能是一个更完整的例子。有人知道更完整的地图吗
int keyCodeForKeyString(char * keyString); // get the Mac keycode for the RUI representation
int keyCodeForKeyString(char * keyString)
{
if (strcmp(keyString, "a") == 0) return 0;
if (strcmp(keyString, "s") == 0) return 1;
if (strcmp(keyString, "d") == 0) return 2;
if (strcmp(keyString, "f") == 0) return 3;
if (strcmp(keyString, "h") == 0) return 4;
if (strcmp(keyString, "g") == 0) return 5;
if (strcmp(keyString, "z") == 0) return 6;
if (strcmp(keyString, "x") == 0) return 7;
if (strcmp(keyString, "c") == 0) return 8;
if (strcmp(keyString, "v") == 0) return 9;
// what is 10?
if (strcmp(keyString, "b") == 0) return 11;
if (strcmp(keyString, "q") == 0) return 12;
if (strcmp(keyString, "w") == 0) return 13;
if (strcmp(keyString, "e") == 0) return 14;
if (strcmp(keyString, "r") == 0) return 15;
if (strcmp(keyString, "y") == 0) return 16;
if (strcmp(keyString, "t") == 0) return 17;
if (strcmp(keyString, "1") == 0) return 18;
if (strcmp(keyString, "2") == 0) return 19;
if (strcmp(keyString, "3") == 0) return 20;
if (strcmp(keyString, "4") == 0) return 21;
if (strcmp(keyString, "6") == 0) return 22;
if (strcmp(keyString, "5") == 0) return 23;
if (strcmp(keyString, "=") == 0) return 24;
if (strcmp(keyString, "9") == 0) return 25;
if (strcmp(keyString, "7") == 0) return 26;
if (strcmp(keyString, "-") == 0) return 27;
if (strcmp(keyString, "8") == 0) return 28;
if (strcmp(keyString, "0") == 0) return 29;
if (strcmp(keyString, "]") == 0) return 30;
if (strcmp(keyString, "o") == 0) return 31;
if (strcmp(keyString, "u") == 0) return 32;
if (strcmp(keyString, "[") == 0) return 33;
if (strcmp(keyString, "i") == 0) return 34;
if (strcmp(keyString, "p") == 0) return 35;
if (strcmp(keyString, "RETURN") == 0) return 36;
if (strcmp(keyString, "l") == 0) return 37;
if (strcmp(keyString, "j") == 0) return 38;
if (strcmp(keyString, "'") == 0) return 39;
if (strcmp(keyString, "k") == 0) return 40;
if (strcmp(keyString, ";") == 0) return 41;
if (strcmp(keyString, "\\") == 0) return 42;
if (strcmp(keyString, ",") == 0) return 43;
if (strcmp(keyString, "/") == 0) return 44;
if (strcmp(keyString, "n") == 0) return 45;
if (strcmp(keyString, "m") == 0) return 46;
if (strcmp(keyString, ".") == 0) return 47;
if (strcmp(keyString, "TAB") == 0) return 48;
if (strcmp(keyString, "SPACE") == 0) return 49;
if (strcmp(keyString, "`") == 0) return 50;
if (strcmp(keyString, "DELETE") == 0) return 51;
if (strcmp(keyString, "ENTER") == 0) return 52;
if (strcmp(keyString, "ESCAPE") == 0) return 53;
// some more missing codes abound, reserved I presume, but it would
// have been helpful for Apple to have a document with them all listed
if (strcmp(keyString, ".") == 0) return 65;
if (strcmp(keyString, "*") == 0) return 67;
if (strcmp(keyString, "+") == 0) return 69;
if (strcmp(keyString, "CLEAR") == 0) return 71;
if (strcmp(keyString, "/") == 0) return 75;
if (strcmp(keyString, "ENTER") == 0) return 76; // numberpad on full kbd
if (strcmp(keyString, "=") == 0) return 78;
if (strcmp(keyString, "=") == 0) return 81;
if (strcmp(keyString, "0") == 0) return 82;
if (strcmp(keyString, "1") == 0) return 83;
if (strcmp(keyString, "2") == 0) return 84;
if (strcmp(keyString, "3") == 0) return 85;
if (strcmp(keyString, "4") == 0) return 86;
if (strcmp(keyString, "5") == 0) return 87;
if (strcmp(keyString, "6") == 0) return 88;
if (strcmp(keyString, "7") == 0) return 89;
if (strcmp(keyString, "8") == 0) return 91;
if (strcmp(keyString, "9") == 0) return 92;
if (strcmp(keyString, "F5") == 0) return 96;
if (strcmp(keyString, "F6") == 0) return 97;
if (strcmp(keyString, "F7") == 0) return 98;
if (strcmp(keyString, "F3") == 0) return 99;
if (strcmp(keyString, "F8") == 0) return 100;
if (strcmp(keyString, "F9") == 0) return 101;
if (strcmp(keyString, "F11") == 0) return 103;
if (strcmp(keyString, "F13") == 0) return 105;
if (strcmp(keyString, "F14") == 0) return 107;
if (strcmp(keyString, "F10") == 0) return 109;
if (strcmp(keyString, "F12") == 0) return 111;
if (strcmp(keyString, "F15") == 0) return 113;
if (strcmp(keyString, "HELP") == 0) return 114;
if (strcmp(keyString, "HOME") == 0) return 115;
if (strcmp(keyString, "PGUP") == 0) return 116;
if (strcmp(keyString, "DELETE") == 0) return 117;
if (strcmp(keyString, "F4") == 0) return 118;
if (strcmp(keyString, "END") == 0) return 119;
if (strcmp(keyString, "F2") == 0) return 120;
if (strcmp(keyString, "PGDN") == 0) return 121;
if (strcmp(keyString, "F1") == 0) return 122;
if (strcmp(keyString, "LEFT") == 0) return 123;
if (strcmp(keyString, "RIGHT") == 0) return 124;
if (strcmp(keyString, "DOWN") == 0) return 125;
if (strcmp(keyString, "UP") == 0) return 126;
fprintf(stderr, "keyString %s Not Found. Aborting...\n", keyString);
exit(EXIT_FAILURE);
}
XCode 7.3和Swift 2.2:
let event1 = CGEventCreateKeyboardEvent(nil, 0x09, true); // cmd-v down
CGEventSetFlags(event1, CGEventFlags.MaskCommand);
CGEventPost(CGEventTapLocation.CGHIDEventTap, event1);
let event2 = CGEventCreateKeyboardEvent(nil, 0x09, false); // cmd-v up
CGEventSetFlags(event2, CGEventFlags.MaskCommand);
CGEventPost(CGEventTapLocation.CGHIDEventTap, event2);
上面的代码模拟按下CMD-V然后释放(又名:粘贴)。它可以工作,谢谢。起初我使用了类似的代码,但出于某种原因,它不起作用。注意:在非美国Mac电脑上,默认情况下,cmd+空格用于更改键盘布局。非美国键盘(全部)不再使用cmd+空格更改键盘布局。我受到了关注。@pkamb我90%确信这样做会在文本框中输入正确的字符,但不会执行诸如触发cmd空格热键之类的操作,这就是为什么文档说需要所有按键。我不知道为什么,但我需要放置usleep(10000);在“向下键”和“向上键”事件之间,否则它不会执行任何操作!它不是特定于键盘布局吗?就像美国键盘一样,如果你在操作系统X中设置的德语键盘布局上使用它,它将不正确?此表中缺少一些键,如“CAPSLOCK”,请在此处找到缺少的键:这是特定于键盘布局的,当你尝试调用快捷键时,可能会非常棘手。。。。如果您愿意,您可以通过将NStInputContext
更改为所需的布局来进行黑客攻击,然后将其设置回原来的布局,这将起作用,但这是一个丑陋的黑客攻击……请注意,有一个Swift3示例