Poszukuję sposobu symulowania naciśnięć klawiszy w systemie OSX. Znalazłem inne rozwiązanie (Simulate keypress for system wide hotkeys) przy użyciu Objective-C, ale muszę to zrobić za pomocą Swift. Jak mogę dostosować CGEventCreateKeyboardEvent?Symulowanie naciśnięcia klawisza za pomocą Swift
Odpowiedz
Kod na tej połączonej odpowiedź jest dość łatwo wymienialne Kod Swift, jednak istnieje kilka pułapek trzeba będzie zająć się po drodze:
CGEventSourceCreate
rzuca CGEventSourceStateID
, który jest typealiase dla a UInt32
, ale stałe takie jak kCGEventSourceStateHIDSystemState
są zdefiniowane jako Int
, więc musisz je rzucić, tj. CGEventSourceStateID(kCGEventSourceStateHIDSystemState)
. Podobnie z CGEventFlags
.
CGEventSourceCreate
i CGEventCreateKeyboardEvent
zwraca (lub Unmanaged<CGEvent>
). Automatycznie wygenerowany Swift API dla Core Graphics nie wie, czy zwrócone obiekty muszą zostać zwolnione przez Ciebie, czy nie, musisz sprawdzić dokumenty API dla tych połączeń, a następnie użyć odpowiednio takeRetainedValue()
lub takeUnretainedValue()
na zwróconej wartości, aby dokonać konwersji je do podstawowego typu, z którym chcesz pracować.
Wreszcie zwracają domyślnie nieopakowane opcje, więc musisz zdecydować, czy chcesz sprawdzić nils, czy po prostu żyć z ekscytacją eksplozji środowiska wykonawczego, jeśli kiedykolwiek ją zwrócą.
Biorąc pod uwagę wszystko, co jest dość proste, aby włączyć Objective-C, w tym odpowiedź wskazującą na naciśnięcie CMD-Space Swift, po prostu starał wklejanie tego do aplikacji na zarysowania i to działało w porządku:
(choć Haven” t sprawdzone docs API dla tego, czy zachowanie jest właściwa rzecz do zrobienia, czy nie)
let src = CGEventSourceCreate(CGEventSourceStateID(kCGEventSourceStateHIDSystemState)).takeRetainedValue()
let cmdd = CGEventCreateKeyboardEvent(src, 0x38, true).takeRetainedValue()
let cmdu = CGEventCreateKeyboardEvent(src, 0x38, false).takeRetainedValue()
let spcd = CGEventCreateKeyboardEvent(src, 0x31, true).takeRetainedValue()
let spcu = CGEventCreateKeyboardEvent(src, 0x31, false).takeRetainedValue()
CGEventSetFlags(spcd, CGEventFlags(kCGEventFlagMaskCommand));
CGEventSetFlags(spcd, CGEventFlags(kCGEventFlagMaskCommand));
let loc = CGEventTapLocation(kCGHIDEventTap)
CGEventPost(loc, cmdd)
CGEventPost(loc, spcd)
CGEventPost(loc, spcu)
CGEventPost(loc, cmdu)
Praca z Swift 3
let src = CGEventSource(stateID: CGEventSourceStateID.hidSystemState)
let cmdd = CGEvent(keyboardEventSource: src, virtualKey: 0x38, keyDown: true)
let cmdu = CGEvent(keyboardEventSource: src, virtualKey: 0x38, keyDown: false)
let spcd = CGEvent(keyboardEventSource: src, virtualKey: 0x31, keyDown: true)
let spcu = CGEvent(keyboardEventSource: src, virtualKey: 0x31, keyDown: false)
spcd?.flags = CGEventFlags.maskCommand;
let loc = CGEventTapLocation.cghidEventTap
cmdd?.post(tap: loc)
spcd?.post(tap: loc)
spcu?.post(tap: loc)
cmdu?.post(tap: loc)
Swift 3
Dla mnie wartości klucza heksadecymalnego takie jak: 0x124 nie działały, ale prosty UInt 124 zrobił lewę!
Miłym zbiorem kodów może być found here! Ten fragment kodu kopiowania i wklejania symuluje naciśnięcie klawisza strzałki w prawo. Zmień numer klucza dla tego, co chcesz symulować:
// Simulate Right Arrow keypress
let NSKeyCodeRightArrow: UInt16 = 124
let keyDownEvent = CGEvent(keyboardEventSource: nil, virtualKey: NSKeyCodeRightArrow, keyDown: true)
keyDownEvent?.flags = CGEventFlags.maskCommand
keyDownEvent?.post(tap: CGEventTapLocation.cghidEventTap)
let keyUpEvent = CGEvent(keyboardEventSource: nil, virtualKey: NSKeyCodeRightArrow, keyDown: false)
keyUpEvent?.flags = CGEventFlags.maskCommand
keyUpEvent?.post(tap: CGEventTapLocation.cghidEventTap)
dziękuję bardzo! – ixany
@Airspeed: dobra odpowiedź. Chociaż możemy uczynić "wartości klucza szesnastkowego" czymś bardziej czytelnym, jak KVK_ANSI_A – Kaunteya
Nie działa już ze Swift 3 :( – Nisba