2012-05-24 2 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 창을여십시오.

이벤트의 출처와 이벤트를 게시 할 위치를 변경하려고 시도했지만 도움이되지 않습니다. 어떤 아이디어? CGEventCreateKeyboardEvent에 대한 문서에서

답변

16

:

문자를 생성하는 데 필요한 모든 키 입력은 보조 키를 포함하여 입력해야합니다. 예를 들어, '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 .: 기본적으로 키보드 레이아웃을 변경하는 데는 Mac 이외의 cmd + 공간이 사용됩니다. –

+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 Keyboard와 같고 OS X에서 설정 한 독일어 키보드 레이아웃이 올바르지 않을 때 이것을 사용한다면? –

0

엑스 코드 7.3 및 2.2는 스위프트 (: 페이스트 AKA)를

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 다음 릴리스 눌림 시뮬레이션한다.

+0

Swift3 예제 [http://stackoverflow.com/questions/27484330/simulate-keypress-using-swift](http://stackoverflow.com/questions/27484330/simulate-keypress-using-swift)가 있습니다. –