如何区分用户点击的键盘事件和生成的键盘事件?

cks*_*ubs 9 input objective-c keyboard-hook

我安装了一个键盘钩子:

CGEventRef myCGEventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {

基本上我想拿用户的键盘水龙头,吃输入,然后发布我自己的输入.

因此,如果他点击"g",我可能想将"foo"发布到文本字段.

我正在写文本域CGEventPostCGEventSetUnicodeString在此处找到:http: //www.mail-archive.com/cocoa-dev@lists.apple.com/msg23343.html

问题是我的每个编程输入的字符都是键盘钩子.所以我不能return NULL在键盘钩子中阻止用户输入......这也阻止了所有程序的输入!

我在C#中使用'inject'标志在Windows端区分它们,请在一年前看到我的问题:如何使用低级8位标志作为条件?

在Objective-C中寻找类似的东西.

Jos*_*ell 6

看一下CGEventSource.h中的注释.将信息放在一起比使用事件服务参考更容易一些.漫长但更正确的方式看起来像创建一个事件源(受内存管理规则约束; CFRelease如果在程序终止之前完成使用它,则需要它):

myEventSource = CGEventSourceCreate(kCGEventSourceStatePrivate);
Run Code Online (Sandbox Code Playgroud)

这将创建具有唯一ID的私有事件源; 然后指出您创建的事件来自那里:

CGEventRef myKeyboardEvent = CGEventCreateKeyboardEvent(myEventSource, 
                                                        keyCode, true);
Run Code Online (Sandbox Code Playgroud)

当一个事件进来时,检查它是否来自你自己:

 if( (CGEventGetType(newEvent) == kCGEventKeyDown) &&
     (CGEventGetIntegerValueField(newEvent, kCGEventSourceStateID) == CGEventSourceGetSourceStateID(myEventSource) ) {
Run Code Online (Sandbox Code Playgroud)

如果需要,还有一个源的用户数据字段,允许您传递任意64位.

快速而肮脏的方法是尝试选择一个不太可能是键盘事件的有意义值的事件字段,kCGMouseEventPressure并将其转换为签名:

CGEventSetIntegerValueField(myKeyboardEvent, 
                            kCGMouseEventPressure, 
                            0xFEEDFACE);
// The field is an int_64 so you could make the sig longer
Run Code Online (Sandbox Code Playgroud)