【发布时间】:2016-01-31 05:28:08
【问题描述】:
我知道其他人也问过类似的问题,但我还没有看到明确的答案,我仍然陷入困境。我正在尝试编写一个 Swift 函数,该函数采用硬件生成的键盘扫描代码,例如来自 NSEvent,并返回特定键排列(Dvorak、Qwerty 等)的 alpha-caps-locked 键的名称。 ) 当前在操作系统中有效(可能与生成代码时的有效排列不同)。
据我了解,这样做的唯一方法是调用一些非常古老的 Carbon 函数,避开 Swift 的许多极端类型安全性,这是我感觉不舒服的事情。这是到目前为止的节目:
import Cocoa
import Carbon
func keyName (scanCode: UInt16) -> String?
{ let maxNameLength = 4, modifierKeys: UInt32 = 0x00000004 // Caps Lock (Carbon Era)
let deadKeys = UnsafeMutablePointer<UInt32>(bitPattern: 0x00000000),
nameBuffer = UnsafeMutablePointer<UniChar>.alloc(maxNameLength),
nameLength = UnsafeMutablePointer<Int>.alloc(1),
keyboardType = UInt32(LMGetKbdType())
let source = TISGetInputSourceProperty ( TISCopyCurrentKeyboardLayoutInputSource()
.takeRetainedValue(),
kTISPropertyUnicodeKeyLayoutData )
let dataRef = unsafeBitCast(source, CFDataRef.self)
let dataBuffer = CFDataGetBytePtr(dataRef)
let keyboardLayout = unsafeBitCast(dataBuffer, UnsafePointer <UCKeyboardLayout>.self)
let osStatus = UCKeyTranslate (keyboardLayout, scanCode, UInt16(kUCKeyActionDown),
modifierKeys, keyboardType, UInt32(kUCKeyTranslateNoDeadKeysMask),
deadKeys, maxNameLength, nameLength, nameBuffer)
switch osStatus
{ case 0: return NSString (characters: nameBuffer, length: nameLength[0]) as String
default: NSLog (“Code: 0x%04X Status: %+i", scanCode, osStatus); return nil }
}
它不会崩溃,在这一点上我几乎认为它本身就是一个游戏成就,但它也不起作用。 UCKeyTranslate 总是返回 -50 的状态,我理解这意味着有一个参数错误。我怀疑“keyboardLayout”,因为它是最复杂的设置。谁能看到参数问题?或者这种事情有更新的框架吗?
【问题讨论】:
-
您看到了吗:How to use UCKeyTranslate?看起来很相似。
-
@Martin 我做了,发现它和 Ken Thomases 的回答很有帮助,但在最终版本中,看起来作者试图在最后一个参数中传递一个指向 Swift 数组的指针,这可能期待更像是指向旧 C 样式数组的指针。我对 Swift 很陌生,但这看起来很危险,我无法让 Swift 接受它。而且我不知道是否有人解决了返回 -50 状态值的问题。
-
不需要
modifierKeys幻数。根据 UCKeyTranslate 文档使用modifierKeys = UInt32(((alphaLock) >> 8) & 0xFF)
标签: swift keyboard-events macos-carbon