【问题标题】:How do I use CGEventKeyboardSetUnicodeString with multiple characters?如何将 CGEventKeyboardSetUnicodeString 与多个字符一起使用?
【发布时间】:2010-01-23 16:52:59
【问题描述】:

我正在尝试使用事件点击来创建一个 OS X 程序,该程序将侦听以音译形式键入的意第绪语并以希伯来语字符发布结果。我做了一个很短的程序来测试我必须做的一件事:http://pastie.org/791398

按原样,程序成功地将每个键入的“q”替换为“w”:

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

但是如何发布一个包含多个字符的字符串呢?例如,如果有人键入“sh”,您可能必须发布一个退格键(以删除单独为“s”发布的字符),然后发布与“sh”相对应的字符。但是,此代码仅导致发布退格:

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

如果这些是基本问题,我深表歉意;我已经阅读了我能找到的所有文档,但我可能还没有完全理解。也有可能我的做法完全错误。

【问题讨论】:

    标签: macos quartz-graphics keypress cgeventtap


    【解决方案1】:

    理想情况下,您应该使用输入法而不是带有事件点击的程序,如果您不需要支持 10.5 之前的版本,则很可能使用 Input Method Kit。为此目的使用事件点击本质上是一个坏主意,因为用户可以更改他/她使用鼠标和键盘输入的位置。因此,如果用户在一个文本字段中键入“s”,然后在另一个文本字段中键入“h”,您将无法区分。

    也就是说,这是您问题的直接答案。

    字符串是按长度计算的,所以不能只提供传入的长度 (1);第二个字符将被忽略。但是,大多数应用程序也不希望每个事件获得多个字符,因此它们只会丢弃剩余的字符。 (终端是一个明显的例外。)

    所以你可以做的就是发布一个包含第二个字符的第二个事件。

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

    在一般情况下(模拟 > 2 次按键),您需要为要插入的每个字符创建一个事件。 This mailing list post 包含一个简单的示例。

    【讨论】:

    • 谢谢!知道这一点真的很有用——你说得对,我应该用 IMKit 制作输入法。 (其实用MacUIM这样的输入法框架会更方便:code.google.com/p/macuim
    【解决方案2】:

    这就是我向第一响应者(前台应用程序)发送字符串的方式

    // 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);
    

    【讨论】:

      猜你喜欢
      • 2017-04-27
      • 2020-10-05
      • 2021-08-16
      • 2016-04-24
      • 1970-01-01
      • 1970-01-01
      • 2011-05-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多