Mac App 注册键盘快捷键

作者: 学无止境吧 | 来源:发表于2017-02-25 14:11 被阅读258次

写个小工具,需要用到键盘快捷键。但是我对于mac os 开发,目前来讲还是个小白。网上一番搜索,得到一些了解,到这里记录一下,便于后来者翻阅。

在mac os中,事件大概有以下几种方式可以捕获进行操作:
1.注册全局事件
2.事件监控回调函数
3.基于NSResponder的回调。

1.注册全局事件

不废话了,直接上代码。
1.使用的是Carbon库,所以需要项目导入Carbon库。


2.在某个地方调用注册代码

#import <Carbon/Carbon.h>

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
  [SomeClass addGlobalHotKey:kVK_ANSI_1];//注册数字按钮1
  [SomeClass addGlobalHotKey:kVK_ANSI_2];//注册数字按钮2
  [SomeClass addGlobalHotKey:kVK_ANSI_3];//注册数字按钮3
}
/**
 * 添加全局的快捷键
 **/
+(void)addGlobalHotKey:(NSInteger)keyCode{
    EventHotKeyRef       gMyHotKeyRef;
    EventHotKeyID        gMyHotKeyID;
    EventTypeSpec        eventType;
    eventType.eventClass = kEventClassKeyboard;
    eventType.eventKind = kEventHotKeyPressed;
    InstallApplicationEventHandler(&GlobalHotKeyHandler,1,&eventType,NULL,NULL);
    gMyHotKeyID.signature = 'abcdef';
    gMyHotKeyID.id = keyCode;
    RegisterEventHotKey(keyCode, 0, gMyHotKeyID,GetApplicationEventTarget(), 0, &gMyHotKeyRef);
// RegisterEventHotKey(keyCode, cmdKey+optionKey, gMyHotKeyID,GetApplicationEventTarget(), 0, &gMyHotKeyRef);
}

上面里面需要注意的:keyCode 是Carbon/HIToolbox/Events.h 文件里面定义好的键盘值,可以自己去看一下。

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
};

如果是组合键需要在RegisterEventHotKey的第二个参数加cmdKey+optionKey 这样子。表示 cmdKey+optionKey+keyCode 键盘上3个按钮同时按下。

RegisterEventHotKey(keyCode, cmdKey+optionKey, gMyHotKeyID,GetApplicationEventTarget(), 0, &gMyHotKeyRef);

另外参数重需要传递一个回调函数过去,也就是InstallApplicationEventHandler这个方法的第一个参数&GlobalHotKeyHandler,所以我们要在文件前面申明这个回调函数。

OSStatus GlobalHotKeyHandler(EventHandlerCallRef nextHandler,EventRef theEvent,
                         void *userData)
{
    EventHotKeyID hkCom;
    GetEventParameter(theEvent,kEventParamDirectObject,typeEventHotKeyID,NULL,
                      sizeof(hkCom),NULL,&hkCom);
    int l = hkCom.id;
    switch (l) {
        case kVK_ANSI_1: //do something
            NSLog(@"kVK_ANSI_1按下");
            break;
        case kVK_ANSI_2:
            NSLog(@"kVK_ANSI_2按下");
            break;
        case kVK_ANSI_3:
            NSLog(@"kVK_ANSI_3按下");
            break;
    }
    return noErr;
}

在对应的case里,可以发送全局通知,呼起业务逻辑。

2.事件监控回调函数

事件监控就是2个简单的函数:


+(void)addMonitorForEvent{
   [NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskFlagsChanged handler:^NSEvent * _Nullable(NSEvent * event) {
       NSUInteger flags = [event modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask;
       if (flags == NSEventModifierFlagCommand) {
           // handle it
           NSLog(@"NSCommandKeyMask");
       }
       NSLog(@"addLocalMonitorForEventsMatchingMask %@",event);
       return event;
   }];
    
    [NSEvent addGlobalMonitorForEventsMatchingMask:NSEventMaskFlagsChanged handler:^(NSEvent *event){
        NSUInteger flags = [event modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask;
        if (flags == NSEventModifierFlagCommand) {
            // handle it
        }
        NSLog(@"addGlobalMonitorForEventsMatchingMask %@",event);
    }];
}

如果app是激活状态按下cmd按钮,则会调用local方法。如果是在非激活状态按下,则会调用global方法。

这个addMonitorForEvent 也是可以在app加载的时候就直接初始化。

3.基于NSResponder的回调。

这个应该是最常用的快捷键了,就是重写view的NSResponder对应的事件函数,达到捕获按键事件处理的效果。

在自己的视图(NSView)上面直接写2个函数,如下:

//需要捕获command + 1234567890事件
- (void)keyDown:(NSEvent *)theEvent{
    NSString *key = [theEvent charactersIgnoringModifiers];
    if([self.numKeyStrArray containsObject:key]){
        if([theEvent modifierFlags] & NSEventModifierFlagCommand){//command+num
            [self pressNum:key];
        }
    }
    [super keyDown:theEvent];
}

-(void)keyUp:(NSEvent *)theEvent {

}

-(void)pressNum:(NSString *)numStr{
      NSLog(@" 按下 commnd + %@",numStr);
}

- (BOOL)acceptsFirstResponder{
    return YES;
}

有补充的欢迎留言。

相关文章

网友评论

  • 猫猫__:你好,请问一下ev_keymap.h里面的媒体键如何监听?

本文标题:Mac App 注册键盘快捷键

本文链接:https://www.haomeiwen.com/subject/vhzgwttx.html