时间:2011-04-30 09:38:32

标签: objective-c input 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端区分它们,请在一年前查看我的问题:How do I use low-level 8 bit flags as conditionals?

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

1 个答案:

答案 0 :(得分:6)

看一下CGEventSource.h中的注释。将信息放在一起比使用Event Services Reference更容易。漫长但更正确的方式看起来像creating an event source(受内存管理规则约束;如果在程序终止之前完成使用它,则需要CFRelease

myEventSource = CGEventSourceCreate(kCGEventSourceStatePrivate);

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

CGEventRef myKeyboardEvent = CGEventCreateKeyboardEvent(myEventSource, 
                                                        keyCode, true);

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

 if( (CGEventGetType(newEvent) == kCGEventKeyDown) &&
     (CGEventGetIntegerValueField(newEvent, kCGEventSourceStateID) == CGEventSourceGetSourceStateID(myEventSource) ) {

如果需要,还有一个user data field源代码可以传递任意64位。

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

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