首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >OS X:检测系统范围的keyDown事件?

OS X:检测系统范围的keyDown事件?
EN

Stack Overflow用户
提问于 2011-01-21 04:50:08
回答 4查看 25K关注 0票数 62

我正在为Mac开发一个打字教程应用程序,它需要将击键转发给它,即使该应用程序不在焦点上。

有没有办法让系统将击键转发给应用程序,可能是通过NSDistributedNotificationCenter?我用谷歌搜索了一下自己,但一直没能找到答案……

编辑:下面是示例代码。

感谢@NSGod为我指明了正确的方向--我最终使用addGlobalMonitorForEventsMatchingMask:handler:方法添加了一个global events monitor,效果非常好。为了完整起见,我的实现如下所示:

代码语言:javascript
运行
复制
// 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上使用一个方法调用。该块是作为参数提供的,直接函数。你可以把它想象成一个内联委托方法。只是因为我花了一段时间才理解,我将在这里一步一步地解决它:

代码语言:javascript
运行
复制
[NSEvent addGlobalMonitorForEventsMatchingMask:NSKeyDownMask

这第一个比特不是问题。您将在NSEvent上调用一个类方法,并告诉它您希望监视哪个事件,在本例中为NSKeyDownMask。可以在here中找到list of masks for supported event types

现在,我们到了棘手的部分: handler,它需要一个块:

代码语言:javascript
运行
复制
handler:^(NSEvent *event){

我花了几次编译错误来纠正这个错误,但(谢谢你Apple)它们是非常有建设性的错误消息。首先要注意的是克拉^。这标志着块的开始。在那之后,在括号里,

代码语言:javascript
运行
复制
NSEvent *event

它声明了您将在块中用来捕获事件的变量。你可以把它叫做

代码语言:javascript
运行
复制
NSEvent *someCustomNameForAnEvent

不要紧,您只需在块中使用该名称即可。然后,这就是所有的事情了。请确保关闭大括号,并使用括号完成方法调用:

代码语言:javascript
运行
复制
}];

你就完事了!这真的是一种“一行”。在应用程序中的什么地方执行这个调用并不重要--我是在AppDelegate的applicationDidFinishLaunching方法中执行的。然后,在块中,您可以从应用程序中调用其他方法。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 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“(至少对于关键事件)。

票数 25
EN

Stack Overflow用户

发布于 2012-06-04 04:01:40

我正在发布适用于我的案例的代码。

我将在应用程序启动后添加全局事件处理程序。我的快捷方式让ctrl+alt+cmd+T打开我的应用程序。

代码语言:javascript
运行
复制
- (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];
        }
    }];

}
票数 15
EN

Stack Overflow用户

发布于 2011-02-18 03:50:58

我发现的问题是,由另一个应用全局注册的任何密钥都不会被捕获……或者至少在我的情况下,也许我做错了什么。

如果你的程序需要显示所有的键,比如"Command-Shift-3“,那么它就不会看到去显示它……因为它被操作系统占用。

还是有人想通了?我很想知道...

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4752427

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档