苹果 MacOSX 程序中如果要检测 ESC 按键, 可不是那么简单. 虽然 NSResponder(包括 NSView 及其子类) 有 keyDown: 方法可以实现, 但如果用户是在输入控件中敲键盘, 那么即使你在 NSWindowController 中也无法检测到 ESC 按键. 似乎 Cocoa 对 ESC 键做了特殊处理.
而且, 有时你希望在整个 App 中检测按键, 而不是只对于当前一个窗口(key window), 那该怎么办? 解决方法是利用事件监听器(Event Monitor).
1 @interface MyController : NSWindowController{ 2 id eventMonitor; 3 } 4 @end 5 6 @implementation MyController 7 - (void)windowDidLoad{ 8 NSEvent* (^handler)(NSEvent*) = ^(NSEvent *theEvent) { 9 NSWindow *targetWindow = theEven.window; 10 if (targetWindow != self.window) { 11 return theEvent; 12 } 13 14 NSEvent *result = theEvent; 15 NSLog(@"event monitor: %@", theEvent); 16 if (theEven.keyCode == 53) { 17 [self myProcessEscKeyDown]; 18 result = nil; // 不让别的控件处理该事件 19 } 20 21 return result; 22 }; 23 eventMonitor = [NSEvent addLocalMonitorForEventsMatchingMask:NSKeyDownMask handler:handler]; 24 } 25 26 - (void)windowWillClose:(NSNotification *)notification{ 27 [NSEvent removeMonitor:eventMonitor]; 28 } @end
上面的示例代码中做了判断, 只对当前控制器管理的窗口的事件进行处理, 如果你要实现程序级别的监听, 就不对窗口进行判断, 并且把上面的代码放在 NSApplicationDelegate 的子类里.