一千萬個為什麽

搜索

Cocoa Virtual Keystrokes Pain

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?

我試過用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);

上面應該發送鍵擊命令+ c,但我得到的只是一聲嘟嘟聲,並且粘貼板內容不變。

我的智慧結束了 - 任何人都可以告訴我我缺少的是什麽,或者指出我為了這麽簡單的東西而忽略了什麽?

最佳答案

只是一個想法... 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

轉載註明原文: Cocoa Virtual Keystrokes Pain