我需要在我的Cocoa应用程序中制作一个全局热键输入框。
我知道有Shortcut Recorder,但这是一个非常古老的解决方案。它使用了已被弃用的Carbon实现的部分,如果我使用它,我就无法将我的应用程序发布到Mac App Store。
是否有任何现成的现代解决方案?有人可以告诉我如何自己制作(我不知道从哪里开始)吗?
我需要在我的Cocoa应用程序中制作一个全局热键输入框。
我知道有Shortcut Recorder,但这是一个非常古老的解决方案。它使用了已被弃用的Carbon实现的部分,如果我使用它,我就无法将我的应用程序发布到Mac App Store。
是否有任何现成的现代解决方案?有人可以告诉我如何自己制作(我不知道从哪里开始)吗?
有一个现代化的框架叫做MASShortcut可以在OS X 10.7+中实现全局快捷键。
并非所有的Carbon都已被弃用。你不能再制作纯Carbon应用程序了,但是一些API仍然存在,并且其中一些仍然是完成某些任务最简单的方法。
其中之一就是Carbon事件热键API。你当然可以使用NSEvent的事件监视器方法来筛选所有事件,但这是不必要的工作。Carbon事件热键API仍然受支持,而且更简单——你只需告诉它你想匹配哪个键以及按下该键时要调用哪个函数。而且还有像DDHotKey这样的Cocoa包装器,使其变得更加简单。
NSEvent
类定义的方法+addGlobalMonitorForEventsMatchingMask:handler:和+addLocalMonitorForEventsMatchingMask:handler:。 事件监视报告以下信息:
该页面显示的代码是为本地事件监视器而编写的,但全局事件监视器的代码相似; 改变的是调用的本地和全局事件监视器是互斥的。例如,全局监视器不会观察安装它的应用程序的事件流。本地事件监视器只观察其应用程序的事件流。要监视所有应用程序(包括“当前”应用程序)的事件,必须安装两个事件监视器。
NSEvent
的方法。_eventMonitor = [NSEvent addLocalMonitorForEventsMatchingMask:
(NSLeftMouseDownMask | NSRightMouseDownMask | NSOtherMouseDownMask | NSKeyDownMask)
handler:^(NSEvent *incomingEvent) {
NSEvent *result = incomingEvent;
NSWindow *targetWindowForEvent = [incomingEvent window];
if (targetWindowForEvent != _window) {
[self _closeAndSendAction:NO];
} else if ([incomingEvent type] == NSKeyDown) {
if ([incomingEvent keyCode] == 53) {
// Escape
[self _closeAndSendAction:NO];
result = nil; // Don't process the event
} else if ([incomingEvent keyCode] == 36) {
// Enter
[self _closeAndSendAction:YES];
result = nil;
}
}
return result;
}];
一旦不再需要监视器,您可以使用以下代码将其移除:
[NSEvent removeMonitor:_eventMonitor];