如何将 CGEventKeyboardSetUnicodeString 与多个字符一起使用?

发布于 2024-08-18 17:35:50 字数 569 浏览 7 评论 0原文

我正在尝试使用事件点击来创建一个 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'; }

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

I'm trying to use event taps to create an OS X program that will listen for Yiddish typed in transliteration and post the result in Hebrew characters. I made a very short program to test one things I'd have to do: http://pastie.org/791398

As is, the program successfully replaces every typed 'q' with 'w':

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

But how does one post a string of more than one character? For instance, if someone types 'sh' you'd presumably have to post a backspace (to delete the character that was posted for 's' alone) and then post the character that corresponds to 'sh'. However, this code results in only a backspace being posted:

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

I apologize if these are basic questions; I have read all the documentation I could find, but I might not have understood it all. It's also possible that I'm going about this entirely the wrong way.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

眼泪都笑了 2024-08-25 17:35:50

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

也就是说,这是对你的问题的直接回答。

字符串是按长度计算的,因此不能只提供传入长度 (1);第二个字符将被忽略。然而,大多数应用程序也不喜欢每个事件获取多个字符,因此它们只会丢弃剩余的字符。 (终端是一个值得注意的例外。)

因此,您可以做的就是简单地发布其中包含第二个字符的第二个事件。

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

在一般情况下(模拟大于 2 次按键),您需要为要插入的每个字符创建一个事件。 此邮件列表帖子包含一个简单的示例。

Ideally you should be using an input method instead of a program with event taps, most likely using Input Method Kit if you don't need to support pre-10.5. Using event taps for this purpose is inherently a bad idea because the user can change where he/she is typing with the mouse as well as the keyboard. So if the user typed a "s" in one text field followed by a "h" in another, you wouldn't be able to tell the difference.

That said, here's a direct answer to your question.

The string is length-counted, so you can't just provide the incoming length (1); the second character will be ignored. However, most applications also don't like to get more than a single character per event, so they'll just discard the remaining characters. (Terminal is a notable exception.)

So what you can do is simply post a second event with the second character in it.

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

In the general case (simulating > 2 keypresses) you'll need to create an event for each character you want to insert. This mailing list post includes a simple example.

独留℉清风醉 2024-08-25 17:35:50

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

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

This is how I send a string to the first responder ( foreground application )

// 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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文