Ich suche nach einer Möglichkeit, Tastenanschläge in OSX zu simulieren. Ich habe eine andere Lösung (Simulate keypress for system wide hotkeys) mit Objective-C gefunden, aber ich muss es mit Swift tun. Wie kann ich CGEventCreateKeyboardEvent anpassen?Simuliert Tastendruck mit Swift
Antwort
Der Code auf dieser Antwort verknüpft ist ziemlich leicht umwandelbar in Swift Code, aber es gibt eine Handvoll gotchas sind, müssen Sie kümmern sich um auf dem Weg:
CGEventSourceCreate
nimmt einen CGEventSourceStateID
, die eine typealiase für a UInt32
, aber die Konstanten wie kCGEventSourceStateHIDSystemState
sind definiert als Int
, also musst du sie umwandeln, zB CGEventSourceStateID(kCGEventSourceStateHIDSystemState)
. Ebenso mit CGEventFlags
.
CGEventSourceCreate
und CGEventCreateKeyboardEvent
geben Sie eine Unmanaged<CGEventSource>
(oder Unmanaged<CGEvent>
) zurück. Die automatisch generierte Swift-API für Core Graphics weiß nicht, ob die zurückgegebenen Objekte von Ihnen freigegeben werden müssen oder nicht. Daher müssen Sie die API-Dokumentation für diese Aufrufe überprüfen und dann takeRetainedValue()
oder takeUnretainedValue()
entsprechend zum zurückgegebenen Wert konvertieren sie in den zugrunde liegenden Typ, mit dem Sie arbeiten möchten.
Schließlich geben sie implizit unverpackte Optionals zurück, also müssen Sie entscheiden, ob Sie nach Nils suchen oder einfach nur mit der Aufregung von Laufzeitexplosionen leben wollen, wenn sie jemals eins zurückgeben.
alles gegeben, was es ist ziemlich einfach, das Objective-C in dieser Antwort zeigt, drücken Cmd-Space Swift zu drehen, ich habe gerade versucht, das Einfügen in einen Kratzer App und es funktionierte gut:
(obwohl ich haven‘ t überprüft die API-Dokumentation für, ob die behalten die richtige Sache zu tun oder nicht)
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)
Arbeiten mit 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
Für mich die hexadezimalen Schlüsselwerte wie: 0x124 hat nicht funktioniert, aber einfache UInt 124 hat den Trick!
Eine schöne Sammlung von Keycodes kann found here sein! Dieses Copy-Paste-Code-Snippet simuliert einen Rechts-Pfeil-Tastendruck. Ändern Sie die Schlüsselnummer für alles, was Sie simulieren möchten:
// 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)
vielen Dank! – ixany
@Airspeed: nette Antwort. Obwohl können wir die "Hex-Schlüsselwerte" zu etwas lesbareres machen wie KVK_ANSI_A – Kaunteya
Funktioniert nicht mehr mit Swift 3 :( – Nisba