Как преобразовать строку в серию нажатий клавиш? - PullRequest
1 голос
/ 03 июля 2010

Я использую CGPostKeyboardEvent((CGCharCode)0, (CGKeyCode)55, true); для имитации нажатий клавиш, но, скажем, у меня была строка, которую я хотел преобразовать в нажатия клавиш.Как мне разделить NSString на отдельные символы, а затем преобразовать их в нажатия клавиш?Спасибо!

Редактировать: ОК. Думаю, я нашел решение, но не могу правильно понять синтаксис.Objective-C действительно сводит меня с ума.

Вот мой код:

int stringLength = [theData length];
  for (int i = 1; i <= stringLength; i++) {
   char *currentCharacter = [theData characterAtIndex:i];
   CGPostKeyboardEvent((CGCharCode)0, (CGKeyCode)keyCodeForKeyString(currentCharacter), true);
}

-(int)keyCodeForKeyString:(char *)keyString
{
 if (strcmp(keyString, "a") == 0) return 0;
 if (strcmp(keyString, "s") == 0) return 1;
 if (strcmp(keyString, "d") == 0) return 2;
 if (strcmp(keyString, "f") == 0) return 3;
 if (strcmp(keyString, "h") == 0) return 4;
 if (strcmp(keyString, "g") == 0) return 5;
 if (strcmp(keyString, "z") == 0) return 6;
 if (strcmp(keyString, "x") == 0) return 7;
 if (strcmp(keyString, "c") == 0) return 8;
 if (strcmp(keyString, "v") == 0) return 9;
 // what is 10?
 if (strcmp(keyString, "b") == 0) return 11;
 if (strcmp(keyString, "q") == 0) return 12;
 if (strcmp(keyString, "w") == 0) return 13;
 if (strcmp(keyString, "e") == 0) return 14;
 if (strcmp(keyString, "r") == 0) return 15;
 if (strcmp(keyString, "y") == 0) return 16;
 if (strcmp(keyString, "t") == 0) return 17;
 if (strcmp(keyString, "1") == 0) return 18;
 if (strcmp(keyString, "2") == 0) return 19;
 if (strcmp(keyString, "3") == 0) return 20;
 if (strcmp(keyString, "4") == 0) return 21;
 if (strcmp(keyString, "6") == 0) return 22;
 if (strcmp(keyString, "5") == 0) return 23;
 if (strcmp(keyString, "=") == 0) return 24;
 if (strcmp(keyString, "9") == 0) return 25;
 if (strcmp(keyString, "7") == 0) return 26;
 if (strcmp(keyString, "-") == 0) return 27;
 if (strcmp(keyString, "8") == 0) return 28;
 if (strcmp(keyString, "0") == 0) return 29;
 if (strcmp(keyString, "]") == 0) return 30;
 if (strcmp(keyString, "o") == 0) return 31;
 if (strcmp(keyString, "u") == 0) return 32;
 if (strcmp(keyString, "[") == 0) return 33;
 if (strcmp(keyString, "i") == 0) return 34;
 if (strcmp(keyString, "p") == 0) return 35;
 if (strcmp(keyString, "RETURN") == 0) return 36;
 if (strcmp(keyString, "l") == 0) return 37;
 if (strcmp(keyString, "j") == 0) return 38;
 if (strcmp(keyString, "'") == 0) return 39;
 if (strcmp(keyString, "k") == 0) return 40;
 if (strcmp(keyString, ";") == 0) return 41;
 if (strcmp(keyString, "\\") == 0) return 42;
 if (strcmp(keyString, ",") == 0) return 43;
 if (strcmp(keyString, "/") == 0) return 44;
 if (strcmp(keyString, "n") == 0) return 45;
 if (strcmp(keyString, "m") == 0) return 46;
 if (strcmp(keyString, ".") == 0) return 47;

 fprintf(stderr, "keyString %s Not Found. Aborting...\n", keyString);
 exit(EXIT_FAILURE);
}

Итак, мой вопрос: как мне получить keyCodeForKeyString(currentCharacter) внутри аргумента CGPostKeyboardEvent?

Ответы [ 2 ]

3 голосов
/ 03 июля 2010

Эта проблема - кошмар, потому что есть функции для перевода кодов клавиш в коды символов, но не наоборот. Помните, что не все символы могут быть напечатаны, и какие из них могут быть напечатаны, зависит от текущей раскладки клавиатуры.

Если ваша цель состоит в том, чтобы какой-то текст появился в другом приложении, вы можете сделать это без перевода отдельных символов с помощью CGEventKeyboardSetUnicodeString. Однако реализация этой функции была нестабильной, поэтому обязательно протестируйте ее на всех версиях ОС, которые вам нужны, а также в приложениях Carbon и Cocoa.

2 голосов
/ 03 июля 2010

Это может быть трудной проблемой, но не по той причине, о которой говорит @JWWalker.

Если вы можете легко преобразовать коды клавиш в символы, то преобразовать символ в код клавиши тривиально. Это взаимно-однозначное соответствие между двумя (у символа есть один код клавиши, а у кода есть один [иногда непечатный] символ), поэтому вы можете легко создать преобразование самостоятельно. Проект ShortcutRecorder имеет подкласс NSValueTransformer , который делает это.

Сложность состоит в том, что отправка нажатий клавиш не всегда приводит к синхронному действию. Поскольку вы (по сути) общаетесь с другим процессом, вы не представляете, сколько времени займет этот процесс для обработки сообщений о событиях и выполнения соответствующих действий. Время между «проводкой» и «обработкой» является неопределенным в зависимости от текущей нагрузки и активности в системе. Обычно это происходит довольно быстро (и таким образом, чтобы выглядеть в основном синхронно), но это не обязательно. Мой конкретный пример связан с работой с сервером монтажа, который иногда очень приятно реагирует на нажатия клавиш cmd - v .

Если все, что вы делаете, имитирует набор текста, то это не должно быть слишком плохо. Вы можете получить char* вашей строки, используя -[NSString UTF8String] (или аналогичный), затем просто перебрать символы, преобразовать их в коды клавиш и опубликовать соответствующие события.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...