我正在为Mac开发一个打字教程应用程序,它需要将击键转发给它,即使该应用程序不在焦点上。
有没有办法让系统将击键转发给应用程序,可能是通过NSDistributedNotificationCenter?我用谷歌搜索了一下自己,但一直没能找到答案……
编辑:下面是示例代码。
感谢@NSGod为我指明了正确的方向--我最终使用addGlobalMonitorForEventsMatchingMask:handler:
方法添加了一个global events monitor,效果非常好。为了完整起见,我的实现如下所示:
// 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。可以在here中找到list of masks for supported event types。
现在,我们到了棘手的部分: handler,它需要一个块:
handler:^(NSEvent *event){
我花了几次编译错误来纠正这个错误,但(谢谢你Apple)它们是非常有建设性的错误消息。首先要注意的是克拉^。这标志着块的开始。在那之后,在括号里,
NSEvent *event
它声明了您将在块中用来捕获事件的变量。你可以把它叫做
NSEvent *someCustomNameForAnEvent
不要紧,您只需在块中使用该名称即可。然后,这就是所有的事情了。请确保关闭大括号,并使用括号完成方法调用:
}];
你就完事了!这真的是一种“一行”。在应用程序中的什么地方执行这个调用并不重要--我是在AppDelegate的applicationDidFinishLaunching方法中执行的。然后,在块中,您可以从应用程序中调用其他方法。
发布于 2011-01-21 08:29:44
如果您满足OS X 10.6+的最低要求,并且可以对事件流进行“只读”访问,那么可以在Cocoa:Cocoa Event-Handling Guide: Monitoring Events中安装全局事件监视器。
如果您需要支持OSX10.5和更早版本,并且只读访问是可以的,并且不介意使用Carbon事件管理器,那么您基本上可以使用GetEventMonitorTarget()
来完成与Carbon相同的操作。(不过,您将很难找到有关该方法的任何(官方)文档)。我相信,该API最先在OSX10.3中可用。
如果您需要对事件流进行读写访问,那么您将需要查看一个稍低级别的ApplicationServices > CoreGraphics:CGEventTapCreate()
and friends的一部分。这在10.4中首次可用。
请注意,所有3种方法都要求用户在System Preferences > Universal access Preferences窗格中启用"Enable Access for assistive devices“(至少对于关键事件)。
发布于 2012-06-04 04:01:40
我正在发布适用于我的案例的代码。
我将在应用程序启动后添加全局事件处理程序。我的快捷方式让ctrl+alt+cmd+T打开我的应用程序。
- (void) applicationWillFinishLaunching:(NSNotification *)aNotification
{
// Register global key handler, passing a block as a callback function
[NSEvent addGlobalMonitorForEventsMatchingMask:NSKeyDownMask
handler:^(NSEvent *event){
// Activate app when pressing cmd+ctrl+alt+T
if([event modifierFlags] == 1835305 && [[event charactersIgnoringModifiers] compare:@"t"] == 0) {
[NSApp activateIgnoringOtherApps:YES];
}
}];
}
发布于 2011-02-18 03:50:58
我发现的问题是,由另一个应用全局注册的任何密钥都不会被捕获……或者至少在我的情况下,也许我做错了什么。
如果你的程序需要显示所有的键,比如"Command-Shift-3“,那么它就不会看到去显示它……因为它被操作系统占用。
还是有人想通了?我很想知道...
https://stackoverflow.com/questions/4752427
复制相似问题