【问题标题】:How to convert a string into a series of keystrokes?如何将字符串转换为一系列击键?
【发布时间】:2011-03-11 07:42:17
【问题描述】:

我正在使用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);
}

所以我的问题是,如何在CGPostKeyboardEvent 的参数中获取keyCodeForKeyString(currentCharacter)

【问题讨论】:

  • char *currentCharacter = [theData characterAtIndex:i]; 行是错误的。 characterAtIndex: 返回 unichar,而不是 char*

标签: objective-c cocoa keyboard


【解决方案1】:

这个问题是一场噩梦,因为有一些函数可以将键码转换为字符码,但反之则不行。请记住,并非所有字符都可以输入,可以输入的字符取决于当前的键盘布局。

如果您的目标是让某些文本出现在另一个应用程序中,您可以使用CGEventKeyboardSetUnicodeString 来实现,而无需翻译单个字符。但是,此功能的实现参差不齐,因此请务必在您关心的所有操作系统版本以及 Carbon 和 Cocoa 应用中进行测试。

【讨论】:

  • 我看到CGEventKeyboardSetUnicodeString 的参数是(CGEventRef event, UniCharCount stringLength, const UniChar unicodeString[] ) 1. 我为CGEventRef 参数使用什么事件? 2. NSString.length 是否与UniCharCount 参数兼容,NSString 是否与const UniChar 参数兼容?感谢您的帮助。
  • 1.使用CGEventCreateKeyboardEvent。 2. Yes, and No. 使用-[NSString getCharacters:range:] 将字符提取到缓冲区中。
  • 那我该如何传递实际的字符串呢?
  • 或者更好,你能告诉我具体怎么做吗?我不太确定如何将 CGEventCreateKeyboardEvent 作为参数传递,因为它需要特定的键码。非常感谢您的帮助。
  • 我认为在这种情况下您传递的关键代码并不重要,我想我使用了 0。
【解决方案2】:

这可能是一个难题,但不是因为@JWWalker 所述的原因。

如果您可以轻松地将键码转换为字符,那么将字符转换为键码就很简单了。这是两者之间的一对一映射(一个字符有一个键码,一个键码有一个 [有时不可打印] 字符),因此您可以轻松地自己构建转换。 ShortcutRecorder 项目有一个 NSValueTransformer subclass 执行此操作。

困难在于发布击键并不总是导致同步操作。由于您(本质上)正在与另一个进程通信,因此您不知道该进程需要多长时间来处理您的事件发布并执行适当的操作。 “发布”和“处理”之间的时间根据系统上的当前负载和活动是不确定的。 通常它发生得相当快(并且以一种看起来大部分是同步的方式),但它不一定是。我的具体示例来自处理粘贴板服务器,它有时会花很长时间来响应 cmd-v 击键。

如果您所做的只是模仿打字,那应该不会太糟糕。您可以使用-[NSString UTF8String](或类似方法)获取字符串的char*,然后简单地遍历字符,将它们转换为键码,然后发布适当的事件。

【讨论】:

  • 字符和键码之间的一对一映射?有数千个 Unicode 字符,但少于 100 个键。
  • @JWWalker 抱歉,我在考虑(主要)ASCII 集,或者物理键盘上的集。
猜你喜欢
  • 2021-06-16
  • 1970-01-01
  • 2015-07-19
  • 2011-10-04
  • 2013-10-05
  • 1970-01-01
  • 2018-02-15
  • 2020-06-30
  • 1970-01-01
相关资源
最近更新 更多