Как мне использовать CGEventKeyboardSetUnicodeString с несколькими символами? - PullRequest
2 голосов
/ 23 января 2010

Я пытаюсь использовать события, чтобы создать программу для OS X, которая будет прослушивать идиш, набранный в транслитерации, и публиковать результат в иврите. Я сделал очень короткую программу для проверки того, что мне нужно сделать: http://pastie.org/791398

Как есть, программа успешно заменяет каждый набранный 'q' на 'w':

if(inputString[0] == 'q') { inputString[0] = 'w'; }

Но как опубликовать строку из более чем одного символа? Например, если кто-то наберет «sh», вам, вероятно, придется опубликовать клавишу возврата (чтобы удалить символ, который был опубликован только для «s»), а затем опубликовать символ, соответствующий «sh». Тем не менее, этот код приводит к тому, что отправляется только backspace:

else if(inputString[0] == 'm') { inputString[0] = '\b'; inputString[1] = 'n'; }

Прошу прощения, если это основные вопросы; Я прочитал всю документацию, которую смог найти, но, возможно, не все понял. Также возможно, что я поступаю совершенно неправильно.

Ответы [ 2 ]

2 голосов
/ 24 января 2010

В идеале вы должны использовать метод ввода вместо программы с событиями, скорее всего, используйте Input Method Kit , если вам не требуется поддержка до 10.5. Использование отводов событий для этой цели по своей сути является плохой идеей, потому что пользователь может изменять, где он / она печатает, с помощью мыши и клавиатуры. Поэтому, если пользователь наберет «s» в одном текстовом поле, а затем «h» в другом, вы не сможете заметить разницу.

Тем не менее, вот прямой ответ на ваш вопрос.

Строка рассчитывается по длине, поэтому вы не можете просто указать входящую длину (1); второй символ будет игнорироваться. Однако большинству приложений также не нравится получать больше одного символа за событие, поэтому они просто отбрасывают оставшиеся символы. (Терминал является заметным исключением.)

Итак, вы можете просто опубликовать второе событие со вторым персонажем.

else if(inputString[0] == 'm') {
  inputString[0] = 'n';
  CGEventKeyboardSetUnicodeString(event, 1, inputString);
  CGEventPost(kCGSessionEventTap, event);
  inputString[0] = '\b';
}

В общем случае (имитация> 2 нажатий клавиш) вам необходимо создать событие для каждого символа, который вы хотите вставить. Это сообщение в списке рассылки содержит простой пример.

1 голос
/ 06 ноября 2016

Так я отправляю строку первому респонденту (приложение переднего плана)

// 1 - Get the string length in bytes.        
NSUInteger l = [string lengthOfBytesUsingEncoding:NSUTF16StringEncoding];

// 2 - Get bytes for unicode characters
UniChar *uc = malloc(l);
[string getBytes:uc maxLength:l usedLength:NULL encoding:NSUTF16StringEncoding options:0 range:NSMakeRange(0, l) remainingRange:NULL];

// 3 - create an empty tap event, and set unicode string
CGEventRef tap = CGEventCreateKeyboardEvent(NULL,0, YES);
CGEventKeyboardSetUnicodeString(tap, string.length, uc);

// 4 - Send event and tear down
CGEventPost(kCGSessionEventTap, tap);
CFRelease(tap);
free(uc);
...