Objective c 如何使用UCKeyTranslate

Objective c 如何使用UCKeyTranslate,objective-c,macos,cocoa,swift,core-services,Objective C,Macos,Cocoa,Swift,Core Services,给定一个不带修改器的按键代码,我想生成按下shift+键的结果。示例:对于标准的美国键盘+给出> 相关的函数是UCKeytranslate,但是我需要一些帮助来获得正确的细节。下面的代码段是一个可以在Xcode中运行的完整程序。程序的目的是生成字符> 该计划的结果是: Keyboard: <TSMInputSource 0x10051a930> KB Layout: U.S. (id=0) Layout: 0x0000000102802000 Status: -50 UnicodeS

给定一个不带修改器的按键代码,我想生成按下shift+键的结果。示例:对于标准的美国键盘+给出>

相关的函数是UCKeytranslate,但是我需要一些帮助来获得正确的细节。下面的代码段是一个可以在Xcode中运行的完整程序。程序的目的是生成字符>

该计划的结果是:

Keyboard: <TSMInputSource 0x10051a930> KB Layout: U.S. (id=0)
Layout: 0x0000000102802000
Status: -50
UnicodeString: 97
String: a
Done
Program ended with exit code: 0
键盘:KB布局:美国(id=0) 布局:0x0000000102802000 状态:-50 销毁:97 字符串:a 多恩 程序以退出代码结束:0 获取布局的部分似乎正在工作,但状态代码表明出现了问题。但是什么呢

import Foundation
import Cocoa
import Carbon
import AppKit

// The current text input source (read keyboard) has a layout in which
// we can lookup how key-codes are resolved.

// Get the a reference keyboard using the current layout.
var unmanagedKeyboard = TISCopyCurrentKeyboardLayoutInputSource()
var keyboard = unmanagedKeyboard.takeUnretainedValue() as TISInputSource
print("Keyboard: ") ; println(keyboard)

// Get the layout
var ptrLayout   = TISGetInputSourceProperty(keyboard, kTISPropertyUnicodeKeyLayoutData)
var layout = UnsafeMutablePointer<UCKeyboardLayout>(ptrLayout)
print("Layout: "); println(layout)

// Let's see what the result of pressing  <shift> and <period>  (hopefully the result is > )
var keycode             = UInt16(kVK_ANSI_Period)                           // Keycode for <period>
var keyaction           = UInt16(kUCKeyActionDisplay)                       // The user is requesting information for key display
var modifierKeyState    = UInt32(1 << 17)                                   // Shift
var keyboardType        = UInt32(LMGetKbdType())
var keyTranslateOptions = UInt32(1 << kUCKeyTranslateNoDeadKeysBit)
var deadKeyState        = UnsafeMutablePointer<UInt32>(bitPattern: 0)       // Is 0 the correct value?
var maxStringLength     = UniCharCount(4)                                   // uint32
var actualStringLength  = UnsafeMutablePointer<UniCharCount>.alloc(1)       //
actualStringLength[0]=16
var unicodeString       = UnsafeMutablePointer<UniChar>.alloc(255)
unicodeString[0] = 97 // a (this value is meant to be overwritten by UCKeyTranslate)
var str = NSString(characters: unicodeString, length: 1)
var result = UCKeyTranslate(layout, keycode, keyaction, modifierKeyState, keyboardType, keyTranslateOptions,
                            deadKeyState, maxStringLength, actualStringLength, unicodeString)

// Print the results
print("Status: "); println(result)
var unichar = unicodeString[0];
print("UnicodeString: "); println(String(unichar))
print("String: "); println(str)
println("Done")
<代码>导入基础 进口可可 进口碳 导入应用程序包 //当前文本输入源(读取键盘)有一个布局,其中 //我们可以查找如何解析关键代码。 //使用当前布局获取一个参考键盘。 var unmanagedKeyboard=TISCopyCurrentKeyboardLayoutInputSource() var keyboard=unmanagedKeyboard.takeUnrepainedValue()作为TIInputSource 打印(“键盘:”);println(键盘) //获取布局 var ptrLayout=TISGetInputSourceProperty(键盘,KTisPropertyYUnicodeKeyLayoutData) 变量布局=不可配置指针(ptrLayout) 印刷(“版面:”);println(布局) //让我们看看按和的结果(希望结果是>) var keycode=UInt16(kVK\u ANSI\u周期)// var keyaction=UInt16(kUCKeyActionDisplay)//用户正在请求有关键显示的信息
var modifierKeyState=UInt32(1对于
kTISPropertyUnicodeKeyLayoutData
TISGetInputSourceProperty()
返回一个
CFDataRef
。您需要获取它的字节指针,并将其视为指向
UCKeyboardLayout
的指针。我不认为这是您对这行所做的:

var layout = UnsafeMutablePointer<UCKeyboardLayout>(ptrLayout)
var布局=不可配置指针(ptrLayout)
我真的不知道Swift,但它可能会起到以下作用:

var layout = UnsafePointer<UCKeyboardLayout>(CFDataGetBytePtr(ptrLayout))
var布局=UnsafePointer(CFDataGetBytePtr(ptrLayout))
或者可能:

var layout = CFDataGetBytePtr(ptrLayout) as UnsafePointer<UCKeyboardLayout>
var layout=CFDataGetBytePtr(ptrLayout)作为非安全指针
另外,
kUCKeyActionDisplay
基本上是无用的。它的目的是返回密钥的标签,但它甚至不能可靠地执行此操作。您可能希望使用
kUCKeyActionDown


对于修饰符,您需要使用Carbon era
shiftKey
位掩码右移8位(如
UCKeyTranslate()
的文档所示).
shiftKey
is
1>8
is
1非常感谢您的建议。我觉得我离解决方案越来越近了-我只需要破解CFDataGetBytePtr问题。uint32注释的原因是我正在为UCKeyTranslate编写绑定,并且需要底层的C类型。Swift程序是为了得到一个可以工作的示例我可以模仿FFI。谢谢你的详尽回答。我在这段代码中使用了未声明类型的“UCKeyboardLayout”
,出现了一个错误。你知道如何修复它吗?10.10.3版的文档说结构
UCKeyboardLayout
被删除了。你需要看看是什么取代了它。PS:我试过查找,但UCKeyboardLayout的文档没有esn现在根本不提Swift:PPS:其他人也有同样的问题:
var layout = CFDataGetBytePtr(ptrLayout) as UnsafePointer<UCKeyboardLayout>