我正在寻找一种在OSX中模拟击键的方法。我找到了另一个使用Objective-C的解决方案(Simulate keypress for system wide hotkeys),但我需要使用Swift。我如何调整CGEventCreateKeyboardEvent?
答案 0 :(得分:11)
使用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)
答案 1 :(得分:9)
该链接答案的代码很容易转换为Swift代码,但是在此过程中需要注意一些问题:
CGEventSourceCreate
需要CGEventSourceStateID
,这是UInt32
的类型值,但kCGEventSourceStateHIDSystemState
等常量定义为Int
,所以你'我必须施放它们,即CGEventSourceStateID(kCGEventSourceStateHIDSystemState)
。与CGEventFlags
一样。
CGEventSourceCreate
和CGEventCreateKeyboardEvent
返回Unmanaged<CGEventSource>
(或Unmanaged<CGEvent>
)。自动生成的Swift API for Core Graphics不知道您是否需要发布返回的对象,因此您需要检查这些调用的API文档,然后使用takeRetainedValue()
或takeUnretainedValue()
因此,在返回的值上,将它们转换为您想要使用的基础类型。
最后,它们会隐式返回未包装的选项,因此您需要决定是否要检查nils,或者只是在运行时发生爆炸时感到兴奋,如果它们返回的话。
鉴于所有这一切都很简单,在那个答案中将Objective-C转换为向Cift空间推送紧急的Cmd-Space,我只是尝试将其粘贴到临时应用程序中并且工作正常:
(虽然我没有检查API文档是否保留是正确的做法)
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)
答案 2 :(得分:2)
我为Swift 4项目做了这个,不要忘记App沙盒不允许应用程序发送这样的击键,因此需要关闭它。这意味着您的应用程序将被禁止进入AppStore。
import Foundation
class FakeKey {
static func send(_ keyCode: CGKeyCode, useCommandFlag: Bool) {
let sourceRef = CGEventSource(stateID: .combinedSessionState)
if sourceRef == nil {
NSLog("FakeKey: No event source")
return
}
let keyDownEvent = CGEvent(keyboardEventSource: sourceRef,
virtualKey: keyCode,
keyDown: true)
if useCommandFlag {
keyDownEvent?.flags = .maskCommand
}
let keyUpEvent = CGEvent(keyboardEventSource: sourceRef,
virtualKey: keyCode,
keyDown: false)
keyDownEvent?.post(tap: .cghidEventTap)
keyUpEvent?.post(tap: .cghidEventTap)
}
}
答案 3 :(得分:1)
Swift 3
对我来说十六进制键值如:0x124不起作用,但简单的UInt 124就可以了!
一组很好的密钥代码可以是found here! 此复制粘贴代码段模拟右箭头按键。更改您想要模拟的任何键号:
// Simulate Right Arrow keypress
let rightArrowKeyCode: UInt16 = 124
let keyDownEvent = CGEvent(keyboardEventSource: nil, virtualKey: rightArrowKeyCode, keyDown: true)
keyDownEvent?.flags = CGEventFlags.maskCommand
keyDownEvent?.post(tap: CGEventTapLocation.cghidEventTap)
let keyUpEvent = CGEvent(keyboardEventSource: nil, virtualKey: rightArrowKeyCode, keyDown: false)
keyUpEvent?.flags = CGEventFlags.maskCommand
keyUpEvent?.post(tap: CGEventTapLocation.cghidEventTap)
<强>更新强> 它在macOS Mojave下无效。
答案 4 :(得分:0)
刺激快捷键/热键的答案组合。 Swift 5.1
let source = CGEventSource(stateID: CGEventSourceStateID.hidSystemState)
let cmdKey: UInt16 = 0x38
let numberThreeKey: UInt16 = 0x14
let cmdDown = CGEvent(keyboardEventSource: source, virtualKey: cmdKey, keyDown: true)
let cmdUp = CGEvent(keyboardEventSource: source, virtualKey: cmdKey, keyDown: false)
let keyThreeDown = CGEvent(keyboardEventSource: source, virtualKey: numberThreeKey, keyDown: true)
let keyThreeUp = CGEvent(keyboardEventSource: source, virtualKey: numberThreeKey, keyDown: false)
fileprivate func testShortcut() {
let loc = CGEventTapLocation.cghidEventTap
cmdDown?.flags = CGEventFlags.maskCommand
cmdUp?.flags = CGEventFlags.maskCommand
keyThreeDown?.flags = CGEventFlags.maskCommand
keyThreeUp?.flags = CGEVentFlags.maskCommand
cmdDown?.post(tap: loc)
keyThreeDown?.post(tap: loc)
cmdUp?.post(tap: loc)
keyThreeUp?.post(tap: loc)
}
手动书写可能包含错误。