当前位置: 首页 > 面试题库 >

如何在Swift中使用CGEventTapCreate?

颛孙越
2023-03-14
问题内容

有没有人设法使此功能在Swift中工作?

苹果文档: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, CGEventType, 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


问题答案:

callback参数CGEventTapCreate()是C函数指针,在 Swift 1.x中 ,无法通过Swift函数参数调用它。

但是,在 Swift 2 (Xcode 7)中,可以使用闭包或全局函数来调用带有函数指针参数的C函数(但要注意,闭包不得捕获其任何本地上下文)。

例如,以下是 对Swift
的接收,筛选和修改按键和释放的完整翻译 :

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, eventTap, 0)
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, .commonModes)
CGEvent.tapEnable(tap: eventTap, enable: true)
CFRunLoopRun()


 类似资料:
  • 问题内容: 我想在我的Swift应用程序中绘制折线。 SWIFT代码 错误: 我找不到解决方案。 问题答案: 首先 ,必须创建一个。 自iOS 7起已弃用,尽管您仍可以在Objective-C中使用它,但在Swift中不支持它。 其次 ,您必须在委托方法中创建并返回一个(不要将其传递给)。 在方法中,传递对象(而不是or )。 以解释传递给哪个对象与返回的对象之间的区别。) 因此,在该方法中,删除

  • 问题内容: 在Objective-C中,我们使用以下代码为视图设置RGB颜色代码: 如何在Swift中使用它? 问题答案: 这是该函数的Swift版本(用于获取值的UIColor表示形式):

  • 问题内容: 有人能帮我吗?我找不到完整的语法示例。 问题答案: 不清楚您要问 的 是什么 ,但我注意到您在代码中有几个错误: 您应该创建使用 返回,因此无需将其包装在内部(也称为实例化新对象)。 完成处理程序是一个闭包,下面是创建该特定闭包的方法: } 这是更新的代码:

  • 问题内容: 我正在尝试将此代码段转换为Swift。由于某些困难,我正在努力下车。 我遇到的第一个也是主要的问题是如何定义和使用C结构。我认为,在上述代码的第一行()中,我认为他们正在定义从struct sockaddr_in(?)调用的实例。我试图声明这样的。 但是我 在调用中 得到了 参数’sin_len’ 的错误 Missing参数 错误 , 这是可以理解的,因为该结构需要多个参数。所以我再次

  • 问题内容: 如何在Swift中使用UserDefaults保存/检索字符串,布尔值和其他数据? 问题答案: 参考:NSUserdefault objectTypes 商店 取回 去掉 删除所有键 Swift 2及以下 商店 取回 去掉 寄存器 registerDefaults:将registrationDictionary添加到每个搜索列表的最后一项。这意味着在NSUserDefaults在所有其

  • 问题内容: 我阅读了Xcode 6的新增功能。本文介绍了有关Xcode 6的一些新功能,并说: 命令行 Xcode的调试器包括Swift语言的交互式版本,称为REPL(Read-Eval-Print- Loop)。使用Swift语法来评估正在运行的应用程序并与之交互,或者在类似脚本的环境中编写新代码。REPL可从Xcode控制台的LLDB或Terminal中获得。 我想知道如何获得REPL? 问题