1

奥拉人,

再一次,我想从使用 SO 的人们共享的知识库中汲取灵感。

我为 OSX 编写了一个将关键事件发送到应用程序的小应用程序。我的目标是 OSX 10.5.x 和更新版本。但是,当我为 10.6.x 构建时也存在问题。一切正常,除非我只发送修饰键;Alt、Command、Control 和 Shift。

问题在于,在两台 MacBook 上,一旦测试人员使用鼠标移动光标或触摸触摸板,修改键的事件似乎就被清除了。

在安装了 XCode 的桌面上,一切正常。就像它应该的那样。在两个不同的 MacBook 上,会出现问题。桌面有一个标准的 101 键键盘和一个多键鼠标。
当鼠标连接到 MacBook 时,会使用带有滚轮的两键鼠标。但是,当没有连接外围设备并使用触摸板时,就会出现问题。

我期望发生的是修改键事件被发送到目标应用程序,用户使用鼠标/触摸板移动光标,按下鼠标/触摸板上的按钮和/或使用修饰键按下事件按下键盘上的键'积极的'。然后,当它们完成时,将发送修改键的键向上事件。

这是我发送按键事件的方式,本示例中的 Shift 键:

case ModKeyShiftDown:
    xEventSource = CGEventSourceCreate(kCGEventSourceStatePrivate);
    xTheCommand = CGEventCreateKeyboardEvent(xEventSource, kVK_Shift, true);
    CGEventSetFlags(xTheCommand, kCGEventFlagMaskAlternate);
    CGEventPost(kCGHIDEventTap, xTheCommand);
    //CGEventPost(kCGSessionEventTap, xTheCommand);
    //CGEventPost(kCGAnnotatedSessionEventTap, xTheCommand);
    CFRelease(xTheCommand);
    CFRelease(xEventSource);
break;

我已使用所有三个标志来创建事件源(kCGEventSourceStatePrivate、kCGEventSourceStateCombinedSessionState 和 kCGEventSourceStateHIDSystemState)。

我尝试使用事件源以及 null 作为第一个参数来创建键盘事件。

我已经尝试过在事件中使用和不使用适当的标志。

我尝试了发布活动的各种组合;kCGHIDEventTap、kCGSessionEventTap 和 kCGAnnotatedSessionEventTap。

为了完整起见,以下是我为 Shift 键发送向上事件的方式:

case ModKeyShiftUp:
    xEventSource = CGEventSourceCreate(kCGEventSourceStatePrivate);
    xTheCommand = CGEventCreateKeyboardEvent(xEventSource, kVK_Shift, false);
    CGEventSetFlags(xTheCommand, 0);
    CGEventPost(kCGHIDEventTap, xTheCommand);
    //CGEventPost(kCGSessionEventTap, xTheCommand);
    //CGEventPost(kCGAnnotatedSessionEventTap, xTheCommand);
    CFRelease(xTheCommand);
    CFRelease(xEventSource);
break;

当测试人员触发修改键按下事件时,他们可以看到光标按预期变化。这让我知道目标应用程序正在处理事件。但是,一旦他们触摸鼠标或触摸板,光标就会变回标准光标,并且鼠标事件会被处理,就好像没有修改键事件处于活动状态一样。

我想知道我发送事件的方式是否有问题。我还想知道是否有另一种方法可以发送正在运行的修饰键事件。

抱歉,如果我说得太多了。我的借口是我只睡了几个小时。:P

谢谢

-isdi-

4

1 回答 1

1

奥拉,

有趣的是,使用 AXUIElementRef 和 A​​XUIElementPostKeyboardEvent 似乎有效。

无论出于何种原因,使用上面的 Accessibility 对象和方法发送关键事件可以解决测试人员的问题。

于 2010-09-27T22:30:38.260 回答