Я новичок в программировании для Mac, поэтому надеюсь, что это не очевидно.
Короче говоря, похоже, что я не получаю несколько событий нажатия клавиш. Я создал этот фрагмент, который никогда не запускает assert и, следовательно, никогда не печатает несколько ключей. Но я получаю отпечатки единственного ключа.
- (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, клавиша вниз помещается в set и удаляется на keyUp. Это означает, что в наборе есть полный набор удерживаемых в данный момент клавиш, что позволяет избежать проблемы «только повторяется последний удерживаемый». Это «достаточно хорошо», поэтому я использую этот метод сейчас. Кажется, он работает хорошо, и поскольку он использует стандартную систему событий клавиатуры (а не HID), проблем с совместимостью быть не должно.
С уважением, Шейн
5 ответов
Я разместил ответ на свой вопрос в самом теле вопроса, но вкратце я нашел статью GameKeyBoardHandling о CocoaDev а> что хорошо работает.
Во-первых, вы проверяете количество символов в событии, которое почти всегда равно 1. Самый распространенный способ получить более 1 символа в событии - это использование метода ввода IME для не западных символов.
Непонятно, чего вы пытаетесь достичь. Если вы пытаетесь отреагировать на нажатие и удержание клавиши пользователем, вы получите несколько событий keyDown :. Вызов isARepeat для первого события вернет NO, для последующих событий - YES.
Если вы пытаетесь обнаружить одновременное нажатие нескольких клавиш, вам необходимо самостоятельно отслеживать состояния клавиш между keyDown: и keyUp :. Итак, если вы нажали f и g одновременно, вы получите один или несколько keyDown: с f и один или несколько keyDown: с g. тогда, если вы отпустите f, все еще удерживая g, вы получите keyUp: for f, продолжая получать keyDown: for g. Вы можете установить флаг для каждой полученной клавиши, а затем сбросить флаг, когда клавиша поднимется.
Если ни одно из этих действий не является тем, что вы пытаетесь сделать, возможно, вы захотите объяснить, что вы делаете дальше.
Каждое NSEvent представляет именно это: одно событие. Когда клавиша выходит из строя, это одно событие. Когда другая клавиша выходит из строя, это другое событие.
Строка characters
- это всего лишь текстовая строка. Это то, что вы бы вставили в свое текстовое хранилище, если бы делали это вручную. Он не сообщает вам, какие символьные клавиши были нажаты; это работа ключевых кодов. Для клавиш-модификаторов это работа битовой маски modifierFlags
.
Если вы пишете игру, вы можете найти либо DDHIDLib или новый HID API в Leopard более полезны. Также помните, что у пользователя может быть несколько клавиатур, поэтому пользователь (пользователи) могут, например, нажать два пробела.
Наконец, пожалуйста, протестируйте свою программу с Дворжаком. Многие приложения, которые пытаются обрабатывать необработанные события клавиатуры, ошибаются и в конечном итоге сбивают нас с толку или даже вообще не работают для нас. Flash имеет давнюю проблему игнорирования клавиш, которые являются знаками препинания в QWERTY, даже если они являются буквенными клавишами в активной раскладке (верно для нескольких клавиш в Dvorak). И не только мы не используем QWERTY; многие неанглоязычные клавиатуры отличаются от раскладки QWERTY.
Что ж, ссылка на принятый ответ мертва, вероятно, это было что-то похожее на:
#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 */ }
}
В исходном коде выше также говорится, что могут быть некоторые аппаратные ограничения, мы должны быть осторожны о.
Я не верю, что при нормальных обстоятельствах вы можете получить одновременно несколько ключей. keyDown
вызывается только тогда, когда нажата клавиша и (я не думаю, что) две клавиши могут быть нажаты в одно и то же время; однако одно нажатие клавиши может генерировать более одного символа в соответствии с документы Apple на NSEvent
. Я предполагаю, что несколько символов относятся к кодовым точкам UNICODE, за исключением того, что NSString
является последовательностью UNICODE, поэтому я не вижу, как вы могли бы сгенерировать более одного символа, кроме как путем создания собственного события.
Однако с клавишами-модификаторами дело обстоит иначе. Если вы ищете клавиши-модификаторы, вам понадобится что-то вроде:
if ([event modifiers] & NSShiftKeyMask) {
...
}
Похожие вопросы
Новые вопросы
cocoa
Cocoa - это среда разработки приложений Apple для macOS, состоящая из Foundation, Application Kit и Core Data. Используйте тег «Какао-touch» для вопросов iOS.