我正在为 Mac OS X 开发一个打字导师应用程序,即使应用程序不在焦点上,也需要将击键转发给它。
有没有办法让系统将击键转发到应用程序,可能通过 NSDistributedNotificationCenter?我用谷歌搜索了自己的愚蠢,并没有找到答案......
编辑: 下面的示例代码。
感谢@NSGod 为我指明了正确的方向——我最终使用该方法添加了一个全局事件监视器addGlobalMonitorForEventsMatchingMask:handler:
,效果很好。为了完整起见,我的实现如下所示:
// register for keys throughout the device...
[NSEvent addGlobalMonitorForEventsMatchingMask:NSKeyDownMask
handler:^(NSEvent *event){
NSString *chars = [[event characters] lowercaseString];
unichar character = [chars characterAtIndex:0];
NSLog(@"keydown globally! Which key? This key: %c", character);
}];
对我来说,棘手的部分是使用块,所以我会给出一些描述以防它帮助任何人:
关于上面的代码需要注意的是,它都是对 NSEvent的单一方法调用。该块作为参数直接提供给函数。你可以把它想象成一个内联委托方法。只是因为这需要一段时间才能让我明白,所以我将在这里一步一步地完成它:
[NSEvent addGlobalMonitorForEventsMatchingMask:NSKeyDownMask
这第一位没有问题。您正在调用 NSEvent 上的类方法,并告诉它您要监视哪个事件,在本例中为 NSKeyDownMask。可以在此处找到支持的事件类型的掩码列表。
现在,我们来到了棘手的部分:处理程序,它需要一个块:
handler:^(NSEvent *event){
我花了一些编译错误来解决这个问题,但是(感谢 Apple)它们是非常有建设性的错误消息。首先要注意的是克拉^。这标志着区块的开始。之后,在括号内,
NSEvent *event
其中声明了您将在块中用于捕获事件的变量。你可以称之为
NSEvent *someCustomNameForAnEvent
没关系,您只会在块中使用该名称。然后,这就是它的全部内容。确保关闭你的花括号和括号以完成方法调用:
}];
你完成了!这确实是一种“单线”。在应用程序中执行此调用的位置无关紧要——我在 AppDelegate 的 applicationDidFinishLaunching 方法中执行此操作。然后,在该块中,您可以从您的应用程序中调用其他方法。