可可虚拟按键痛

发布于 2024-08-29 01:23:41 字数 2741 浏览 10 评论 0原文

我正在编写一个应用程序,通过将突出显示的文本复制到 NSPasteboard 的 GeneralPasteboard 中来响应热键。在这里寻找发送虚拟击键的解决方案后,我发现了这个: 如何向 Objective-c 中的活动应用程序发送“Cmd-C”击键,或告诉应用程序执行复制操作?

I尝试了 NSAppleScript 建议的 applescript:

NSLog(@"Hotkey Pressed");
NSPasteboard *pasteboard = [NSPasteboard generalPasteboard]; 

NSAppleScript *playScript;
playScript = [[NSAppleScript alloc] initWithSource:@"tell application \"System Events\" to keystroke \"c\" using command down"];

if([playScript isCompiled] == NO){
[playScript compileAndReturnError:nil];
}

id exerror = [playScript executeAndReturnError:nil];

if(exerror == nil){
 NSLog(@"Script Failed");
}

它有效,但仅在我第一次按下热键时有效。随后的每次点击都不会抓取突出显示的文本。再次运行脚本之前,generalPasteboard 仍然包含相同的内容。在运行代码之前清除 GeneralPasteboard 是没有用的,因为这样代码在尝试读取粘贴板内容时会失败。这是日志:

 Pastify[16929:a0b] woooooooo! I'm being CALLED
 Pastify[16929:a0b] Hotkey Pressed
 Pastify[16929:a0b] Error loading /Library/ScriptingAdditions/Adobe Unit Types.osax/Contents/MacOS/Adobe Unit Types:  dlopen(/Library/ScriptingAdditions/Adobe Unit Types.osax/Contents/MacOS/Adobe Unit Types, 262): no suitable image found.  Did find:
    /Library/ScriptingAdditions/Adobe Unit Types.osax/Contents/MacOS/Adobe Unit Types: no matching architecture in universal wrapper
 Pastify: OpenScripting.framework - scripting addition "/Library/ScriptingAdditions/Adobe Unit Types.osax" declares no loadable handlers.
 Pastify[16929:a0b] Size of copiedItems: 1
 Pastify[16929:a0b] Content of paste: 2010-04-19 03:41:04.355 Pastify[16929:a0b] woooooooo! I'm being CALLED
 Pastify[16929:a0b] Hotkey Pressed
 Pastify[16929:a0b] Size of copiedItems: 1
 Pastify[16929:a0b] Content of paste: 2010-04-19 03:41:04.355 Pastify[16929:a0b] woooooooo! I'm being CALLED
 Pastify[16929:a0b] Hotkey Pressed
 Pastify[16929:a0b] Size of copiedItems: 1
 Pastify[16929:a0b] Content of paste: 2010-04-19 03:41:04.355 Pastify[16929:a0b] woooooooo! I'm being CALLED

所以我尝试了下一个建议的解决方案:

 CFRelease(CGEventCreate(NULL));

 CGEventRef event1, event2, event3, event4;
 event1 = CGEventCreateKeyboardEvent (NULL, (CGKeyCode)50, true);
 event2 = CGEventCreateKeyboardEvent (NULL, (CGKeyCode)8, true);
 event3 = CGEventCreateKeyboardEvent (NULL, (CGKeyCode)8, false);
 event4 = CGEventCreateKeyboardEvent (NULL, (CGKeyCode)50, false);

 CGEventPost(kCGHIDEventTap, event1);
 CGEventPost(kCGHIDEventTap, event2);
 CGEventPost(kCGHIDEventTap, event3);
 CGEventPost(kCGHIDEventTap, event4);

上面应该发送击键 Command + c,但我得到的只是一声蜂鸣声,并且粘贴板内容没有更改。

我束手无策 - 谁能启发我,让我明白我错过了什么,或者指出我在如此简单的事情上忽略了什么?

I'm writing an application to respond on a hotkey by copying highlighted text into NSPasteboard's generalPasteboard. After looking around here for a solution for sending virtual keystrokes, I found this: How to send a "Cmd-C" keystroke to the active application in objective-c, or tell the application to do a copy operation?

I tried the applescript suggested with NSAppleScript:

NSLog(@"Hotkey Pressed");
NSPasteboard *pasteboard = [NSPasteboard generalPasteboard]; 

NSAppleScript *playScript;
playScript = [[NSAppleScript alloc] initWithSource:@"tell application \"System Events\" to keystroke \"c\" using command down"];

if([playScript isCompiled] == NO){
[playScript compileAndReturnError:nil];
}

id exerror = [playScript executeAndReturnError:nil];

if(exerror == nil){
 NSLog(@"Script Failed");
}

It works, but only on the first time I hit the hotkey. Each subsequent hit will not grab the highlighted text. The generalPasteboard still contains the same contents as before the script is run again. Clearing the generalPasteboard before I run the code is no use, because then the code fails when attempting to read the pasteboard contents. Here's the log:

 Pastify[16929:a0b] woooooooo! I'm being CALLED
 Pastify[16929:a0b] Hotkey Pressed
 Pastify[16929:a0b] Error loading /Library/ScriptingAdditions/Adobe Unit Types.osax/Contents/MacOS/Adobe Unit Types:  dlopen(/Library/ScriptingAdditions/Adobe Unit Types.osax/Contents/MacOS/Adobe Unit Types, 262): no suitable image found.  Did find:
    /Library/ScriptingAdditions/Adobe Unit Types.osax/Contents/MacOS/Adobe Unit Types: no matching architecture in universal wrapper
 Pastify: OpenScripting.framework - scripting addition "/Library/ScriptingAdditions/Adobe Unit Types.osax" declares no loadable handlers.
 Pastify[16929:a0b] Size of copiedItems: 1
 Pastify[16929:a0b] Content of paste: 2010-04-19 03:41:04.355 Pastify[16929:a0b] woooooooo! I'm being CALLED
 Pastify[16929:a0b] Hotkey Pressed
 Pastify[16929:a0b] Size of copiedItems: 1
 Pastify[16929:a0b] Content of paste: 2010-04-19 03:41:04.355 Pastify[16929:a0b] woooooooo! I'm being CALLED
 Pastify[16929:a0b] Hotkey Pressed
 Pastify[16929:a0b] Size of copiedItems: 1
 Pastify[16929:a0b] Content of paste: 2010-04-19 03:41:04.355 Pastify[16929:a0b] woooooooo! I'm being CALLED

So I tried the next suggested solution:

 CFRelease(CGEventCreate(NULL));

 CGEventRef event1, event2, event3, event4;
 event1 = CGEventCreateKeyboardEvent (NULL, (CGKeyCode)50, true);
 event2 = CGEventCreateKeyboardEvent (NULL, (CGKeyCode)8, true);
 event3 = CGEventCreateKeyboardEvent (NULL, (CGKeyCode)8, false);
 event4 = CGEventCreateKeyboardEvent (NULL, (CGKeyCode)50, false);

 CGEventPost(kCGHIDEventTap, event1);
 CGEventPost(kCGHIDEventTap, event2);
 CGEventPost(kCGHIDEventTap, event3);
 CGEventPost(kCGHIDEventTap, event4);

The above should send the keystrokes Command + c, but all I get is a beep, and the pasteboard contents are unchanged.

I'm at wits end - can anyone enlighten me as to what I'm missing or point me out to what I'm overlooking for something so simple?

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

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

发布评论

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

评论(3

浅沫记忆 2024-09-05 01:23:41

您是否有理由无法为此使用服务?

如果您确实想通过合成事件来做到这一点,那么最好的选择是发布修改后的键盘事件而不是向下/向上 - 有关更多详细信息,请参阅此问题。

在 Mac OS X 中模拟按键事件

如果这不起作用,好吧,你知道在哪里可以找到我:-)

Is there a reason you can't use a service for this?

If you really want to do it by synthesizing events, your best bet is to post a modified keyboard event rather than down/up - see this question for more details.

Simulating key press events in Mac OS X

If that doesn't work, well, you know where to find me :-)

南巷近海 2024-09-05 01:23:41

只是一个想法... cmd-c 技巧适用于最前面的应用程序。我怀疑,第一次运行热键来触发此操作时,正确的应用程序位于最前面,cmd-c 有效,然后您的应用程序会对粘贴板执行某些操作。第二次运行时,热键被激活,但之前的应用程序不再位于最前面,因此 cmd-c 不起作用。本质上,您正在将 cmd-c 发送到其他应用程序。也许您的应用程序已经出现在前面或其他一些。

为了避免此问题,您需要确保您的目标应用程序位于最前面。因此,首先您需要某种方法来找出最前面的应用程序是什么,然后在执行 cmd-c 之前激活该应用程序。例如,在 applescript 中,如果我想在 Safari 上运行 cmd-c,我会使用:

tell application "Safari" to activate
tell application "System Events" to keystroke "c" using command down

Just a thought... the cmd-c trick works on the frontmost application. I suspect that the first time you run the hotkey to trigger this that the proper application is frontmost, cmd-c works, then your application does something with the pasteboard. On second run the hotkey is activated but the previous application is no longer frontmost so cmd-c does not work. In essence you're sending cmd-c to some other application. Maybe your application has come to the front or some other.

To avoid this problem you need to make sure the application you are targeting is frontmost. So first you need some way to find out what the frontmost application is and then just before you perform cmd-c activate that application. For example in applescript if I wanted to run cmd-c on Safari I would use:

tell application "Safari" to activate
tell application "System Events" to keystroke "c" using command down
記柔刀 2024-09-05 01:23:41

我真的不明白你为什么要这样做,但如果你想确保你的事件进入特定的进程,那么使用 CGEventPost 的“ToPSN”变体。

I really don't understand why you're doing this at all, but if you want to make sure your events go to a specific process, then use the "ToPSN" variant of CGEventPost.

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