你如何在Swift中使用CGEventTapCreate?
有没有人设法让这个功能在
Swift中工作?
这是去年的参考SO帖子:Using CGEventTapCreate Trouble with parameters in Swift Apple Doc:https://developer.apple.com/library/prerelease/mac/documentation/Carbon/Reference/QuartzEventServicesRef/index.html#//apple_ref/c/func/CGEventTapCreate 以下是CGEventTapCallBack的定义方式: typealias CGEventTapCallBack = CFunctionPointer<((CGEventTapProxy,CGEventType,CGEvent!,UnsafeMutablePointer<Void>) -> Unmanaged<CGEvent>!)> 以下是我编写块的方法: let eventTapCallBackBlock : @objc_block (CGEventTapProxy,CGEventRef,UnsafeMutablePointer<Void>) -> CGEventRef = { (eventTapProxy: CGEventTapProxy,eventType: CGEventType,event: CGEventRef,refcon: UnsafeMutablePointer<Void>) in return event } 然后我用回调参数调用CGEventTapCreate,如unsafeBitCast(eventTapCallBackBlock,CGEventTapCallBack.self) 我得到一个有效的CFMachPortRef,但在运行时我在第一个事件上遇到访问冲突异常.它似乎“似乎”我在当前发布状态下接近迅速解决方案. 使用Xcode版本6.4 解决方法
CGEventTapCreate()的回调参数是一个C函数指针,
在Swift 1.x中,不可能使用Swift函数参数调用它. 但是,在Swift 2(Xcode 7)中,C函数接受函数指针参数 作为一个例子,这里是一个完整的翻译 import Foundation func myCGEventCallback(proxy : CGEventTapProxy,type : CGEventType,event : CGEvent,refcon : UnsafeMutablePointer<Void>) -> Unmanaged<CGEvent>? { if [.KeyDown,.KeyUp].contains(type) { var keyCode = CGEventGetIntegerValueField(event,.KeyboardEventKeycode) if keyCode == 0 { keyCode = 6 } else if keyCode == 6 { keyCode = 0 } CGEventSetIntegerValueField(event,.KeyboardEventKeycode,keyCode) } return Unmanaged.passRetained(event) } let eventMask = (1 << CGEventType.KeyDown.rawValue) | (1 << CGEventType.KeyUp.rawValue) guard let eventTap = CGEventTapCreate(.CGSessionEventTap,.HeadInsertEventTap,.Default,CGEventMask(eventMask),myCGEventCallback,nil) else { print("failed to create event tap") exit(1) } let runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault,eventTap,0) CFRunLoopAddSource(CFRunLoopGetCurrent(),runLoopSource,kCFRunLoopCommonModes) CGEventTapEnable(eventTap,true) CFRunLoopRun() Swift 3更新: import Foundation func myCGEventCallback(proxy: CGEventTapProxy,type: CGEventType,event: CGEvent,refcon: UnsafeMutableRawPointer?) -> Unmanaged<CGEvent>? { if [.keyDown,.keyUp].contains(type) { var keyCode = event.getIntegerValueField(.keyboardEventKeycode) if keyCode == 0 { keyCode = 6 } else if keyCode == 6 { keyCode = 0 } event.setIntegerValueField(.keyboardEventKeycode,value: keyCode) } return Unmanaged.passRetained(event) } let eventMask = (1 << CGEventType.keyDown.rawValue) | (1 << CGEventType.keyUp.rawValue) guard let eventTap = CGEvent.tapCreate(tap: .cgSessionEventTap,place: .headInsertEventTap,options: .defaultTap,eventsOfInterest: CGEventMask(eventMask),callback: myCGEventCallback,userInfo: nil) else { print("failed to create event tap") exit(1) } let runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault,.commonModes) CGEvent.tapEnable(tap: eventTap,enable: true) CFRunLoopRun() (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |