CGEventPost - 模拟键盘事件时可能出现的错误?

Ben*_*ard 13 macos quartz-graphics

我有一个非常简单的代码块,用于模拟键盘事件.下面的简单例子应该输入"Cz" - 换档键下降,c键下降,c上升,换档上升.然后z键向下和向上.

看来有时订单会变得混乱.当我创建一个计时器来每秒调用这个例程时,输出应该是CzCzCzCz ....但这是我得到的:

CZcZCZCzczCzczCzczCZCZCzCz

我会再次运行它:

CzCzCzCzCZCzCZCzCZCzCZCzCZCzCzCz

不同.同样错了.

代码:

e1 = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)56, true);
CGEventPost(kCGSessionEventTap, e1);
CFRelease(e1);
e2 = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)8, true);
CGEventPost(kCGSessionEventTap, e2);
CFRelease(e2);
e3 = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)8, false);
CGEventPost(kCGSessionEventTap, e3);
CFRelease(e3);
e4 = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)56, false);
CGEventPost(kCGSessionEventTap, e4);
CFRelease(e4);

e7 = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)6, true);
CGEventPost(kCGSessionEventTap, e7);
CFRelease(e7);
e8 = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)6, false);
CGEventPost(kCGSessionEventTap, e8);
CFRelease(e8);
Run Code Online (Sandbox Code Playgroud)

在如何实现shift键的keydown和keyup时,我是否缺少一些东西?我认为这可能是一个错误 - 我会在哪里举报?

Ben*_*ard 23

我找到了一种可靠的方法来发布修改过的键盘事件 - 它不遵循Apple的文档中的示例(这不起作用)但似乎有意义,最重要的是,WORKS.

而不是发送'shift键down'和'shift key up'消息(按照文档中的说明),您需要在按键上设置修饰符标志.这是输出大写Z的方法.

CGEventRef event1, event2;
event1 = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)6, true);//'z' keydown event
CGEventSetFlags(event1, kCGEventFlagMaskShift);//set shift key down for above event
CGEventPost(kCGSessionEventTap, event1);//post event
Run Code Online (Sandbox Code Playgroud)

然后我释放'z'键以获得完整性(同时设置shift-flag,但不确定这是否正确).

event2 = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)6, false);
CGEventSetFlags(event2, kCGEventFlagMaskShift);
CGEventPost(kCGSessionEventTap, event2);
Run Code Online (Sandbox Code Playgroud)

最后(并且奇怪地)你需要发送shift键的'key up'事件:

  e5 = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)56, false);
CGEventPost(kCGSessionEventTap, e5);
Run Code Online (Sandbox Code Playgroud)

完成后,不要忘记发布您的活动.

我希望这对某人有用 - 我花了很长时间才能使这个工作.


val*_*exa 10

最简洁的方法是将当前修饰符标记与所需修饰符的标志进行按位OR运算,例如:

CGEventFlags flags = kCGEventFlagMaskShift;
CGEventRef ev;
CGEventSourceRef source = CGEventSourceCreate (kCGEventSourceStateCombinedSessionState);

//press down            
ev = CGEventCreateKeyboardEvent (source, keyCode, true);    
CGEventSetFlags(ev,flags | CGEventGetFlags(ev)); //combine flags                        
CGEventPost(kCGHIDEventTap,ev);
CFRelease(ev);              

//press up                                  
ev = CGEventCreateKeyboardEvent (source, keyCode, false);                       
CGEventSetFlags(ev,flags | CGEventGetFlags(ev)); //combine flags                        
CGEventPost(kCGHIDEventTap,ev); 
CFRelease(ev);              

CFRelease(source);
Run Code Online (Sandbox Code Playgroud)