【问题标题】:How to tell the difference between a user-tapped keyboard event and a generated one?如何区分用户点击的键盘事件和生成的键盘事件?
【发布时间】:2011-04-30 09:38:31
【问题描述】:

我已经安装了一个键盘挂钩:

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# 的 Windows 端使用“injected”标志对它们进行了区分,一年前在这里查看我的问题:How do I use low-level 8 bit flags as conditionals?

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

【问题讨论】:

    标签: objective-c input keyboard-hook


    【解决方案1】:

    看看 CGEventSource.h 中的 cmets。将信息放在一起比使用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
    

    【讨论】:

    • 嗯,所示的 MouseEventPressure 的“快速而肮脏”的编辑给了我以下 : kCGErrorIllegalArgument: CGEventSetIntegerValueField: invalid event
    • @cksubs:您是否尝试过我提到的真正方法,使用用户数据字段作为事件源?
    • 今晚我会再看一遍。当我最初问这个问题时,我被困住了,但现在不记得为什么了。你对这个错误有什么想法吗? stackoverflow.com/questions/7102883/…
    • 我很抱歉造成混乱。我想你明白0xFEEDFACE 只是垃圾,并且会在 Quick & Dirty 方法失败时尝试在源上设置用户数据字段。我发布了对您的新问题的答案,并进行了解释。希望能帮助到你;如果您还有其他问题,请告诉我。
    猜你喜欢
    • 2010-11-09
    • 2012-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多