Mac App 注冊鍵盤快捷鍵

寫個小工具,需要用到鍵盤快捷鍵。但是我對于mac os 開發(fā),目前來講還是個小白。網(wǎng)上一番搜索,得到一些了解,到這里記錄一下,便于后來者翻閱。

在mac os中,事件大概有以下幾種方式可以捕獲進行操作:
1.注冊全局事件
2.事件監(jiān)控回調(diào)函數(shù)
3.基于NSResponder的回調(diào)。

1.注冊全局事件

不廢話了,直接上代碼。
1.使用的是Carbon庫,所以需要項目導(dǎo)入Carbon庫。


2.在某個地方調(diào)用注冊代碼

#import <Carbon/Carbon.h>

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
  [SomeClass addGlobalHotKey:kVK_ANSI_1];//注冊數(shù)字按鈕1
  [SomeClass addGlobalHotKey:kVK_ANSI_2];//注冊數(shù)字按鈕2
  [SomeClass addGlobalHotKey:kVK_ANSI_3];//注冊數(shù)字按鈕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的第二個參數(shù)加cmdKey+optionKey 這樣子。表示 cmdKey+optionKey+keyCode 鍵盤上3個按鈕同時按下。

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

另外參數(shù)重需要傳遞一個回調(diào)函數(shù)過去,也就是InstallApplicationEventHandler這個方法的第一個參數(shù)&GlobalHotKeyHandler,所以我們要在文件前面申明這個回調(diào)函數(shù)。

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

在對應(yīng)的case里,可以發(fā)送全局通知,呼起業(yè)務(wù)邏輯。

2.事件監(jiān)控回調(diào)函數(shù)

事件監(jiān)控就是2個簡單的函數(shù):


+(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是激活狀態(tài)按下cmd按鈕,則會調(diào)用local方法。如果是在非激活狀態(tài)按下,則會調(diào)用global方法。

這個addMonitorForEvent 也是可以在app加載的時候就直接初始化。

3.基于NSResponder的回調(diào)。

這個應(yīng)該是最常用的快捷鍵了,就是重寫view的NSResponder對應(yīng)的事件函數(shù),達到捕獲按鍵事件處理的效果。

在自己的視圖(NSView)上面直接寫2個函數(shù),如下:

//需要捕獲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;
}

有補充的歡迎留言。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • ¥開啟¥ 【iAPP實現(xiàn)進入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個線程,因...
    小菜c閱讀 7,294評論 0 17
  • 手機端配置tcp方式連接 su setprop service.adb.tcp.port 5555 stop ad...
    yoyo鹿鳴閱讀 5,815評論 0 4
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,716評論 25 709
  • 前段時間給美國的D小姐發(fā)郵件,收到自動回復(fù),說正在旅行。后來才知道,她是去了內(nèi)華達沙漠里的Burning Man(...
    任寧閱讀 514評論 0 1
  • 大地給天空寫了封信, 托太陽 將她熱切的思念 舞動成絲 裊裊地送達。 天空讀完信, 把要說的話聚成云, 請?zhí)栒粘?..
    晨光微曉閱讀 289評論 0 1

友情鏈接更多精彩內(nèi)容