OS X:检测系统范围内的keyDown事件? [英] OS X: Detect system-wide keyDown events?

查看:67
本文介绍了OS X:检测系统范围内的keyDown事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为Mac OS X开发一个打字指导应用程序,即使该应用程序没有重点,它也需要将击键转发给它.

I'm working on a typing-tutor application for Mac OS X that needs to have keystrokes forwarded to it, even when the application is not in focus.

是否可以通过NSDistributedNotificationCenter使系统将击键转发到应用程序?我愚蠢地用Google搜索,却找不到答案...

Is there a way to have the system forward keystrokes to the app, possibly through NSDistributedNotificationCenter? I've googled myself silly, and haven't been able to find an answer...

编辑:下面的示例代码.

感谢@NSGod向我指出正确的方向-我最终添加了

Thanks @NSGod for pointing me in the right direction -- I ended up adding a global events monitor using the method addGlobalMonitorForEventsMatchingMask:handler:, which works beautifully. For completeness, my implementation looks like this:

// 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);

}];

对我来说,棘手的部分是使用块,因此我将给出一些说明,以防它对任何人有帮助:

For me, the tricky part was using blocks, so I'll give a little description in case it helps anyone:

关于上面的代码,需要注意的是,在NSEvent上,所有这些都是单个方法调用.该块作为参数直接提供给该函数.您可能会认为它类似于内联委托方法.仅仅因为这花了我一段时间,我将在这里逐步进行操作:

The thing to notice about the above code is that it's all one single method call on NSEvent. The block is supplied as an argument, directly to the function. You could think of it kind of like an inline delegate method. Just because this took a while to sink in for me, I'm going to work through it step by step here:

[NSEvent addGlobalMonitorForEventsMatchingMask:NSKeyDownMask

这第一位没问题.您正在NSEvent上调用类方法,并告诉您要监视的事件,在本例中为NSKeyDownMask.

This first bit is no problem. You're calling a class method on NSEvent, and telling it which event you're looking to monitor, in this case NSKeyDownMask. A list of masks for supported event types can be found here.

现在,我们进入棘手的部分:处理程序,该处理程序需要一个块:

Now, we come to the tricky part: handler, which expects a block:

handler:^(NSEvent *event){

我花了一些编译错误才能实现此目的,但是(感谢Apple)它们是非常有建设性的错误消息.首先要注意的是克拉^.这标志着该块的开始.之后,在括号内

It took me a few compile errors to get this right, but (thank you Apple) they were very constructive error messages. The first thing to notice is the carat ^. That signals the start of the block. After that, within the parentheses,

NSEvent *event

在块中声明将用于捕获事件的变量.您可以称之为

Which declares the variable that you'll be using within the block to capture the event. You could call it

NSEvent *someCustomNameForAnEvent

没关系,您只需在代码块中使用该名称即可.然后,仅此而已.确保关闭花括号和方括号以完成方法调用:

doesn't matter, you'll just be using that name within the block. Then, that's just about all there is to it. Make sure to close your curly brace, and bracket to finish the method call:

}];

您完成了!这确实是一种单线".不管您在应用程序中的哪个位置执行此调用都没关系-我在AppDelegate的applicationDidFinishLaunching方法中执行此操作.然后,您可以在该块中,从您的应用程序中调用其他方法.

And you're done! This really is kind of a 'one-liner'. It doesn't matter where you execute this call within your app -- I do it in the AppDelegate's applicationDidFinishLaunching method. Then, within the block, you can call other methods from within your app.

推荐答案

如果您对OS X 10.6+的最低要求还可以,并且可以通过只读"方式访问事件流,则可以安装可可中的全球事件监控器: 可可事件处理指南:监视事件.

If you are okay with a minimum requirement of OS X 10.6+, and can suffice with "read-only" access to the stream of events, you can install a global event monitor in Cocoa: Cocoa Event-Handling Guide: Monitoring Events.

如果您需要支持OS X 10.5和更早版本,并且只读访问是可行的,并且不介意使用Carbon Event Manager,则基本上可以使用GetEventMonitorTarget()进行Carbon等效. (尽管您将很难找到关于该方法的任何(官方)文档).我相信该API最早是在OS X 10.3中提供的.

If you need to support OS X 10.5 and earlier, and read-only access is okay, and don't mind working with the Carbon Event Manager, you can basically do the Carbon-equivalent using GetEventMonitorTarget(). (You will be hard-pressed to find any (official) documentation on that method though). That API was first available in OS X 10.3, I believe.

如果您需要对事件流的读写访问权限,那么您将需要查看一个较低级别的API,该API是ApplicationServices> CoreGraphics的一部分:

If you need read-write access to the event stream, then you will need to look at a slightly lower-level API that is part of ApplicationServices > CoreGraphics:CGEventTapCreate() and friends. This was first available in 10.4.

请注意,所有3种方法都要求用户在系统偏好设置">通用访问"偏好设置窗格中启用启用对辅助设备的访问"(至少对于关键事件).

Note that all 3 methods will require that the user have "Enable access for assistive devices" enabled in the System Preferences > Universal Access preference pane (at least for key events).

这篇关于OS X:检测系统范围内的keyDown事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆