2009-07-20 52 views
3

我是Mac編程的新手,所以我希望這不是很明顯。多鍵可可(OS X)

總之,我似乎沒有得到多個按鍵事件。我創建了這個片段,它永遠不會觸發斷言,因此絕不會打印多個鍵。不過,我獲得了單鍵版畫。

- (void)keyDown:(NSEvent *) theEvent { 
    NSString *characters = [theEvent characters]; 
    assert([characters length]<2); 
    for (int i=0;i<[characters length];++i) { 
     NSLog(@"k=[%d]\n", [characters characterAtIndex:i]); 
    } 
    } 

有誰知道我在做什麼錯?如果您有興趣,我需要爲OpenGL查看應用程序提供多個按鍵。也許我完全不在這種應用程序的標記。

編輯:進一步研究後,我發現這一點: http://www.cocoadev.com/index.pl?GameKeyBoardHandling 這使得基於這裏的討論,意義上,只有最後一個鍵重複。當引發keyDown事件時,向下鍵被放置並在keyUp上移除。這意味着該套具有完整的當前按下鍵,避免了唯一重複最後一次持有的問題。 它'夠好',所以我現在使用這種方法。它似乎工作得很好,並且因爲它使用標準鍵盤事件系統(而不是HID),所以不應該有任何兼容性問題。

問候, 巴蒂爾

回答

0

我不相信,你可以在正常情況下一次接收多個按鍵。 keyDown只有在按下某個鍵時才被調用,並且(我不認爲)兩個鍵可以在同一時間按下;然而,根據the Apple docs on NSEvent,單次按鍵可能會生成多個字符。我最好的猜測是多個字符是指UNICODE代碼點,但NSString是UNICODE序列,所以我看不到如何通過創建自己的事件來生成多個字符。

但是,修飾鍵是一個不同的故事。如果你正在尋找的組合鍵,那麼你就需要像:

if ([event modifiers] & NSShiftKeyMask) { 
    ... 
} 
+0

「我最好的猜測是多個字符引用的是UNICODE代碼點,但NSString是UNICODE序列,所以我看不到如何通過創建自己的事件來生成多個字符。」首先,它是Unicode,不是UNICODE。其次,`unichar`是兩個字節;一個`unichar`只能容納一個UTF-16編碼單元。在基礎多語言平面之外(即U + FFFF以上),角色必須表示爲兩個形成代理對的單身漢。 – 2009-07-20 03:04:27

+0

好吧,但我應該至少得到每個持有的密鑰重複按鍵事件。有關我的意思的更多信息,請參閱下面的答案。 – Shane 2009-07-20 05:46:40

+0

您的意思是Jon Steinmetz的回答。 (訂單是不固定的,可以隨着投票而改變。) – 2009-07-20 14:42:19

1

的一件事是你正在測試中,幾乎總是1.最常見的方式,以獲得超過事件的字符數對於非西方字符使用IME輸入法時,事件中有1個字符。

目前還不清楚你正在努力完成什麼。如果您試圖對按住按鍵的用戶做出反應,您將獲得多個keyDown:事件。在第一個事件上調用isARepeat將返回NO,在隨後的事件中它將返回YES。

如果您嘗試同時檢測多個按鍵,則需要在keyDown:和keyUp:之間自行跟蹤按鍵狀態。所以如果你同時按下f和g,你將得到一個keyDown或更多的keyDown:使用f和一個或多個keyDown:使用g。那麼如果你在釋放f的同時仍然持有g,你會得到一個keyUp:for f,同時繼續接收keyDown:g。您可以爲每個鍵設置一個標誌,然後在鍵上升時清除該標誌。

如果這些都不是你想要做的,那麼你可能想解釋你正在做的更進一步。

+0

好的,如果每個獨特的按鍵都有一個NSEvent,那麼爲什麼我不按每個按下鍵重複按鍵事件?例如,如果我按住'a',等待,然後按住's',那麼我應該看到單獨的重複KeyDown事件爲兩個鍵被觸發,是的?似乎發生的事情是我只拿到最新的按下鍵。 這是我的意思(從我發佈的代碼)的調試日誌。如果我按住'a'(97),然後等待,然後按住's'(115),您會看到97次重複停止,並且只有115次重複。一次只能重複一個鍵? 「 K = [97] K = [97] K = [97] K = [115] K = [115] K = [115] 」 – Shane 2009-07-20 05:43:13

2

每個NSEvent代表的只是:一個事件。當某個鍵失效時,這是一個事件。當另一個關鍵點出現故障時,這是另一個事件。

characters字符串就是:文本字符串。如果您手動執行此操作,則會插入到文本存儲中。它不會告訴你哪些字符鍵被按下;這是關鍵代碼的工作。對於修飾鍵,它是modifierFlags位掩碼的作業。

如果您正在編寫遊戲,您可能會發現DDHIDLib或Leopard中新的HID API更有用。另外,請記住,用戶可能有多個鍵盤,因此用戶可以按兩個空格鍵。

最後,請用Dvorak測試您的程序。許多嘗試處理原始鍵盤事件的應用程序都會導致錯誤,最終導致我們感到困惑,甚至根本無法爲我們工作。即使在活動佈局中的字母鍵(Dvorak中的幾個鍵都是真的),Flash仍然存在一個長期存在的問題,即忽略QWERTY中標點符號的鍵。我們並不是唯一不使用QWERTY的人;許多非英語鍵盤偏離QWERTY佈局。

1

好,接受的答案的鏈接是死的,可能是類似於:

#import <Carbon/Carbon.h> // for kVK_* names 

- (void)keyDown:(NSEvent *event) 
{ 
    unsigned keyCode = [event keyCode]; 
    if (keyCode < 128) keysDown[keyCode] = YES; 
} 

- (void)keyUp:(NSEvent *event) 
{ 
    unsigned keyCode = [event keyCode]; 
    if (keyCode < 128) keysDown[keyCode] = NO; 
} 

- (void)whereverYouUpdateTheStateOfYourGame 
{ 
    if (keysDown[kVK_ANSI_A] && !keysDown[kVK_ANSI_D]) { /* move left */ } 
    if (keysDown[kVK_ANSI_D] && !keysDown[kVK_ANSI_A]) { /* move right */ } 
    if (keysDown[kVK_ANSI_W] && !keysDown[kVK_ANSI_S]) { /* move up */ } 
    if (keysDown[kVK_ANSI_S] && !keysDown[kVK_ANSI_W]) { /* move down */ } 
} 

上面也source of code指出,一些硬件的限制可能是我們應該注意的事項。