非NSResponder类捕捉按键消息[How to capture ESC key in a Cocoa application]

非NSResponder类捕捉按键消息[How to capture ESC key in a Cocoa application],第1张

概述From: http://www.ideawu.com/blog/2013/04/how-to-capture-esc-key-in-a-cocoa-application.html   http://forums.macrumors.com/showthread.php?t=780577 You may want to capture(or intercept, detect) the ESC

From: http://www.ideawu.com/blog/2013/04/how-to-capture-esc-key-in-a-cocoa-application.html

  http://forums.macrumors.com/showthread.php?t=780577


You may want to capture(or intercept,detect) the ESC key press in a Cocoa application,capture the ESC key down in Application scope for the whole app,or just in Window scope for some certain windows.

The NSApplicationDelegate is not a subclass of NSResponder,so you can not implement the keyDown: method int app delegate. The NSWindowController is a subclass of NSResponder,you may implement keyDown: method in it,but it will not get invoked when user press the ESC key(with exceptions) and not when user is tyPing in a text input.

The solution is to use a Event Monitor.

Here’s the sample codes:

 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

All the stuff is down in a NSWindowController subclass,if you want to implement a key capture in application scope,put these codes in the application delegate,replace windowDIDLoad: withapplicationDIDFinishLaunching:windowWillClose: with applicationWillTerminate:.

 7  - (voID)windowDIDLoad{

Register a keyboard event handler just as window is loaded.

10          if (targetwindow != self.window) {11              return theEvent;12          }

Let events in other windows pass,we only handle events of the window this controller managed.

16          if (theEven.keyCode == 53) {17              [self myProcessEscKeyDown: theEvent];18              result = nil;19          }

Detect ESC key down event,process it,and drop the event(return nil) so the responder chain will never kNow.

23      eventMonitor = [NSEvent addLocalMonitorForEventsMatchingMask:NSKeyDownMask handler:handler];

BesIDes NSKeyDown,there are NSKeyUp,NSleftMouseUp,NSleftMouseDown,etc. But we only monitor key down event in this example,so set the mask to NSKeyDownMask.

26  - (voID)windowWillClose:(NSNotification *)notification{27      [NSEvent removeMonitor:eventMonitor];28  }

Deattach the event monitor when window close.

discussions on other approaches

You can achIEve it by implementing the sendEvent: of a NSWindow subclass,and you need to use this NSWindow subclass to build up UI in Interface Builder,not the default NSWindow class. I don’t recommend you to do in this way,because it will add two extra files in you project.

A NSWindowController’s keyDown: will get a ESC press event if the first responder is a WebVIEw,I don’t kNow what have the WebVIEw done to hand over the event to the controller even there are still other vIEws in the vIEw hIErachy. Please let me kNow if you kNow the reason.

Cocoa Event Architecture and Responder Chain


Responder chain

NSEvent keyCode List

/*	 *  Summary:	 *    Virtual keycodes	 *  	 *  discussion:	 *    These constants are the virtual keycodes defined originally in	 *    InsIDe Mac Volume V,pg. V-191. They IDentify physical keys on a	 *    keyboard. Those constants with "ANSI" in the name are labeled	 *    according to the key position on an ANSI-standard US keyboard.	 *    For example,kVK_ANSI_A indicates the virtual keycode for the key	 *    with the letter 'A' in the US keyboard layout. Other keyboard	 *    layouts may have the 'A' key label on a different physical key;	 *    in this case,pressing 'A' will generate a different virtual	 *    keycode.	 */	enum {	  kVK_ANSI_A                    = 0x00,kVK_ANSI_S                    = 0x01,kVK_ANSI_D                    = 0x02,kVK_ANSI_F                    = 0x03,kVK_ANSI_H                    = 0x04,kVK_ANSI_G                    = 0x05,kVK_ANSI_Z                    = 0x06,kVK_ANSI_X                    = 0x07,kVK_ANSI_C                    = 0x08,kVK_ANSI_V                    = 0x09,kVK_ANSI_B                    = 0x0B,kVK_ANSI_Q                    = 0x0C,kVK_ANSI_W                    = 0x0D,kVK_ANSI_E                    = 0x0E,kVK_ANSI_R                    = 0x0F,kVK_ANSI_Y                    = 0x10,kVK_ANSI_T                    = 0x11,kVK_ANSI_1                    = 0x12,kVK_ANSI_2                    = 0x13,kVK_ANSI_3                    = 0x14,kVK_ANSI_4                    = 0x15,kVK_ANSI_6                    = 0x16,kVK_ANSI_5                    = 0x17,kVK_ANSI_Equal                = 0x18,kVK_ANSI_9                    = 0x19,kVK_ANSI_7                    = 0x1A,kVK_ANSI_Minus                = 0x1B,kVK_ANSI_8                    = 0x1C,kVK_ANSI_0                    = 0x1D,kVK_ANSI_RightBracket         = 0x1E,kVK_ANSI_O                    = 0x1F,kVK_ANSI_U                    = 0x20,kVK_ANSI_leftBracket          = 0x21,kVK_ANSI_I                    = 0x22,kVK_ANSI_P                    = 0x23,kVK_ANSI_L                    = 0x25,kVK_ANSI_J                    = 0x26,kVK_ANSI_Quote                = 0x27,kVK_ANSI_K                    = 0x28,kVK_ANSI_Semicolon            = 0x29,kVK_ANSI_Backslash            = 0x2A,kVK_ANSI_Comma                = 0x2B,kVK_ANSI_Slash                = 0x2C,kVK_ANSI_N                    = 0x2D,kVK_ANSI_M                    = 0x2E,kVK_ANSI_Period               = 0x2F,kVK_ANSI_Grave                = 0x32,kVK_ANSI_KeypadDecimal        = 0x41,kVK_ANSI_KeypadMultiply       = 0x43,kVK_ANSI_Keypadplus           = 0x45,kVK_ANSI_KeypadClear          = 0x47,kVK_ANSI_KeypaddivIDe         = 0x4B,kVK_ANSI_KeypadEnter          = 0x4C,kVK_ANSI_Keypadminus          = 0x4E,kVK_ANSI_KeypadEquals         = 0x51,kVK_ANSI_Keypad0              = 0x52,kVK_ANSI_Keypad1              = 0x53,kVK_ANSI_Keypad2              = 0x54,kVK_ANSI_Keypad3              = 0x55,kVK_ANSI_Keypad4              = 0x56,kVK_ANSI_Keypad5              = 0x57,kVK_ANSI_Keypad6              = 0x58,kVK_ANSI_Keypad7              = 0x59,kVK_ANSI_Keypad8              = 0x5B,kVK_ANSI_Keypad9              = 0x5C	};		/* keycodes for keys that are independent of keyboard layout*/	enum {	  kVK_Return                    = 0x24,kVK_Tab                       = 0x30,kVK_Space                     = 0x31,kVK_Delete                    = 0x33,kVK_Escape                    = 0x35,kVK_Command                   = 0x37,kVK_Shift                     = 0x38,kVK_CapsLock                  = 0x39,kVK_Option                    = 0x3A,kVK_Control                   = 0x3B,kVK_RightShift                = 0x3C,kVK_Rightoption               = 0x3D,kVK_RightControl              = 0x3E,kVK_Function                  = 0x3F,kVK_F17                       = 0x40,kVK_VolumeUp                  = 0x48,kVK_VolumeDown                = 0x49,kVK_Mute                      = 0x4A,kVK_F18                       = 0x4F,kVK_F19                       = 0x50,kVK_F20                       = 0x5A,kVK_F5                        = 0x60,kVK_F6                        = 0x61,kVK_F7                        = 0x62,kVK_F3                        = 0x63,kVK_F8                        = 0x64,kVK_F9                        = 0x65,kVK_F11                       = 0x67,kVK_F13                       = 0x69,kVK_F16                       = 0x6A,kVK_F14                       = 0x6B,kVK_F10                       = 0x6D,kVK_F12                       = 0x6F,kVK_F15                       = 0x71,kVK_Help                      = 0x72,kVK_Home                      = 0x73,kVK_PageUp                    = 0x74,kVK_ForwardDelete             = 0x75,kVK_F4                        = 0x76,kVK_End                       = 0x77,kVK_F2                        = 0x78,kVK_PageDown                  = 0x79,kVK_F1                        = 0x7A,kVK_leftArrow                 = 0x7B,kVK_RightArrow                = 0x7C,kVK_DownArrow                 = 0x7D,kVK_UpArrow                   = 0x7E	};		/* ISO keyboards only*/	enum {	  kVK_ISO_Section               = 0x0A	};		/* JIS keyboards only*/	enum {	  kVK_JIS_Yen                   = 0x5D,kVK_JIS_Underscore            = 0x5E,kVK_JIS_KeypadComma           = 0x5F,kVK_JIS_Eisu                  = 0x66,kVK_JIS_Kana                  = 0x68	};
总结

以上是内存溢出为你收集整理的非NSResponder类捕捉按键消息[How to capture ESC key in a Cocoa application]全部内容,希望文章能够帮你解决非NSResponder类捕捉按键消息[How to capture ESC key in a Cocoa application]所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/web/1052349.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存