2012-05-24 26 views
11

OSXのキーストロークをシミュレートする必要があります。ここで私はそれを行う方法は次のとおりです。システム全体のホットキーのキー入力をシミュレート

-(void)execute { 
    CGEventSourceRef sourceRef = 
    CGEventSourceCreate(kCGEventSourceStateHIDSystemState); 

    CGEventRef keyPress = CGEventCreateKeyboardEvent (sourceRef, (CGKeyCode)keyCode, true); 
    CGEventRef keyUnpress = CGEventCreateKeyboardEvent (sourceRef, (CGKeyCode)keyCode, false); 

    CGEventSetFlags(keyPress, modifierFlags); 
    CGEventPost(kCGHIDEventTap, keyPress); 

    //unpressing the acualkey 
    CGEventPost(kCGHIDEventTap, keyUnpress); 

    CFRelease(keyPress); 
    CFRelease(keyUnpress); 
    CFRelease(sourceRef); 
} 

これは、任意のアプリ内のすべてのホットキーや、簡単なキーストロークのために正常に動作しますが、スポットライトやCMD +を起動する例オプション+スペースため、システム全体のショートカットでは動作しません。 shift + 4をスクリーンショットにするか、ctrl + ` iTerm2ウィンドウを開きます。

イベントの送信元とイベントを送信する場所を変更しようとしましたが失敗しました。何か案は?

答えて

16

CGEventCreateKeyboardEventのドキュメントから:

文字を生成するのに必要なすべてのキーストロークは、修飾キーを含む、入力する必要があります。たとえば、 'Z'を作成するには、SHIFTキーを押し下げ、 'z'キーを押し下げてからSHIFTと 'z'キーを離してください:

したがって、オプション修飾子でスペースを押して放して、オプションスペースをトリガーします。オプションを押す、スペースを押す、スペースを解放する、オプションを解除する必要があります。

補足として、opt-spaceはデフォルトでは何も行いません。 cmd-spaceはSpotlight検索ホットキー、cmd-opt-spaceはSpotlightウィンドウのホットキーです。

ので、このコードはSpotlight検索ポップアップ表示されます:@ abarnertの答えは素晴らしいですが、レコードの

- (void)execute { 
    CGEventSourceRef src = 
    CGEventSourceCreate(kCGEventSourceStateHIDSystemState); 

    CGEventRef cmdd = CGEventCreateKeyboardEvent(src, 0x38, true); 
    CGEventRef cmdu = CGEventCreateKeyboardEvent(src, 0x38, false); 
    CGEventRef spcd = CGEventCreateKeyboardEvent(src, 0x31, true); 
    CGEventRef spcu = CGEventCreateKeyboardEvent(src, 0x31, false); 

    CGEventSetFlags(spcd, kCGEventFlagMaskCommand); 
    CGEventSetFlags(spcu, kCGEventFlagMaskCommand); 

    CGEventTapLocation loc = kCGHIDEventTap; // kCGSessionEventTap also works 
    CGEventPost(loc, cmdd); 
    CGEventPost(loc, spcd); 
    CGEventPost(loc, spcu); 
    CGEventPost(loc, cmdu); 

    CFRelease(cmdd); 
    CFRelease(cmdu); 
    CFRelease(spcd); 
    CFRelease(spcu); 
    CFRelease(src); 
} 
+0

ありがとう、ありがとう。最初は同様のコードを使用しましたが、何らかの理由でうまく動作しませんでした。 –

+0

P.S:Macではcmd + spaceはデフォルトでキーボードレイアウトを変更するために使用されます。 –

+0

キーボードイベントを投稿するのには、少し奇妙なことがたくさんあります。また、あなたが望むやり方で何かを得るために、試行錯誤しなければならないことがあります。この特定のケースでは、ドキュメントは具体的にあなたが間違っていたことに対処していますが、それは実際にはまれです... – abarnert

4

をし、それはあなたがマニュアルに従ってそれを行う必要がある方法です、私の元のコードも動作します。私は、この質問には関係のない別の問題があることを知りました。

修飾キーをキー入力に適用する必要がある場合は、すべての修飾キーを個別に押すことなく、CGEventSetFlags(keyPress, modifierFlags);のように追加できます。そのアプローチはうまくいきますが、私はまだ何らかの欠点を見つけられておらず、コードの可読性が良い方法です。

7

ここでCGKeyCodeリストを希望する人は、the RUI projectの部分表を持つ関数です。

thisがより完全な例です。誰かがより完全な地図を知っていますか?

int keyCodeForKeyString(char * keyString); // get the Mac keycode for the RUI representation 

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; 
    if (strcmp(keyString, "TAB") == 0) return 48; 
    if (strcmp(keyString, "SPACE") == 0) return 49; 
    if (strcmp(keyString, "`") == 0) return 50; 
    if (strcmp(keyString, "DELETE") == 0) return 51; 
    if (strcmp(keyString, "ENTER") == 0) return 52; 
    if (strcmp(keyString, "ESCAPE") == 0) return 53; 

    // some more missing codes abound, reserved I presume, but it would 
    // have been helpful for Apple to have a document with them all listed 

    if (strcmp(keyString, ".") == 0) return 65; 

    if (strcmp(keyString, "*") == 0) return 67; 

    if (strcmp(keyString, "+") == 0) return 69; 

    if (strcmp(keyString, "CLEAR") == 0) return 71; 

    if (strcmp(keyString, "/") == 0) return 75; 
    if (strcmp(keyString, "ENTER") == 0) return 76; // numberpad on full kbd 

    if (strcmp(keyString, "=") == 0) return 78; 

    if (strcmp(keyString, "=") == 0) return 81; 
    if (strcmp(keyString, "0") == 0) return 82; 
    if (strcmp(keyString, "1") == 0) return 83; 
    if (strcmp(keyString, "2") == 0) return 84; 
    if (strcmp(keyString, "3") == 0) return 85; 
    if (strcmp(keyString, "4") == 0) return 86; 
    if (strcmp(keyString, "5") == 0) return 87; 
    if (strcmp(keyString, "6") == 0) return 88; 
    if (strcmp(keyString, "7") == 0) return 89; 

    if (strcmp(keyString, "8") == 0) return 91; 
    if (strcmp(keyString, "9") == 0) return 92; 

    if (strcmp(keyString, "F5") == 0) return 96; 
    if (strcmp(keyString, "F6") == 0) return 97; 
    if (strcmp(keyString, "F7") == 0) return 98; 
    if (strcmp(keyString, "F3") == 0) return 99; 
    if (strcmp(keyString, "F8") == 0) return 100; 
    if (strcmp(keyString, "F9") == 0) return 101; 

    if (strcmp(keyString, "F11") == 0) return 103; 

    if (strcmp(keyString, "F13") == 0) return 105; 

    if (strcmp(keyString, "F14") == 0) return 107; 

    if (strcmp(keyString, "F10") == 0) return 109; 

    if (strcmp(keyString, "F12") == 0) return 111; 

    if (strcmp(keyString, "F15") == 0) return 113; 
    if (strcmp(keyString, "HELP") == 0) return 114; 
    if (strcmp(keyString, "HOME") == 0) return 115; 
    if (strcmp(keyString, "PGUP") == 0) return 116; 
    if (strcmp(keyString, "DELETE") == 0) return 117; 
    if (strcmp(keyString, "F4") == 0) return 118; 
    if (strcmp(keyString, "END") == 0) return 119; 
    if (strcmp(keyString, "F2") == 0) return 120; 
    if (strcmp(keyString, "PGDN") == 0) return 121; 
    if (strcmp(keyString, "F1") == 0) return 122; 
    if (strcmp(keyString, "LEFT") == 0) return 123; 
    if (strcmp(keyString, "RIGHT") == 0) return 124; 
    if (strcmp(keyString, "DOWN") == 0) return 125; 
    if (strcmp(keyString, "UP") == 0) return 126; 

    fprintf(stderr, "keyString %s Not Found. Aborting...\n", keyString); 
    exit(EXIT_FAILURE); 
} 
+0

キーボードレイアウト固有ではありませんか?ちょうどUSキーボードのように、OS Xで設定されているドイツ語のキーボードレイアウトのようにこれを使用すると正しくないでしょうか? –

0

XCodeの7.3スイフト2.2:

let event1 = CGEventCreateKeyboardEvent(nil, 0x09, true); // cmd-v down 
CGEventSetFlags(event1, CGEventFlags.MaskCommand); 
CGEventPost(CGEventTapLocation.CGHIDEventTap, event1); 

let event2 = CGEventCreateKeyboardEvent(nil, 0x09, false); // cmd-v up 
CGEventSetFlags(event2, CGEventFlags.MaskCommand); 
CGEventPost(CGEventTapLocation.CGHIDEventTap, event2); 

上記のコードは、CMD-Vは、次に(:ペーストAKA)解放押下をシミュレート。

+0

Swift3の例があることに注意してください[http://stackoverflow.com/questions/27484330/simulate-keypress-using-swift](http://stackoverflow.com/questions/27484330/simulate-keypress-using-swift) –

関連する問題