Cómo usar UCKeyTranslate
Dado un código de tecla para una tecla presionada sin modificadores, quiero producir el resultado de presionar la tecla Mayús +. Ejemplo: para un teclado estándar de EE. UU. <shift> + <period> da>.
La función relevante es UCKeytranslate, pero necesito un poco de ayuda para obtener los detalles correctos. El fragmento a continuación es un programa completo listo para ejecutarse en XCode. La intención del programa se da <period> para producir el personaje>.
El resultado del programa es:
Keyboard: <TSMInputSource 0x10051a930> KB Layout: U.S. (id=0)
Layout: 0x0000000102802000
Status: -50
UnicodeString: 97
String: a
Done
Program ended with exit code: 0
La parte que obtiene el diseño parece estar funcionando, pero el código de estado revela que algo salió mal. ¿Pero que?
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")
EDITAR
He reescrito el fragmento siguiendo las sugerencias de Ken Thomases. Algunos trucos de:Grafito También se utilizó un programa Swift que utiliza códigos de teclas.
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.
let keyboard = TISCopyCurrentKeyboardInputSource().takeRetainedValue()
let rawLayoutData = TISGetInputSourceProperty(keyboard, kTISPropertyUnicodeKeyLayoutData)
print("Keyboard: ") ; println(keyboard)
// Get the layout
var layoutData = unsafeBitCast(rawLayoutData, CFDataRef.self)
var layout: UnsafePointer<UCKeyboardLayout> = unsafeBitCast(CFDataGetBytePtr(layoutData), UnsafePointer<UCKeyboardLayout>.self)
print("Layout: "); println(layout)
print("KbdType "); println(LMGetKbdType()) // Sanity check (prints 44)
var keycode = UInt16(kVK_ANSI_Period) // Keycode for a
var keyaction = UInt16(kUCKeyActionDisplay)
var modifierKeyState = UInt32(1 << 1) // Shift
var keyboardType = UInt32(LMGetKbdType())
var keyTranslateOptions = OptionBits(kUCKeyTranslateNoDeadKeysBit)
var deadKeyState = UInt32(0) // Is 0 the correct value?
var maxStringLength = UniCharCount(4) // uint32
var chars: [UniChar] = [0,0,0,0]
var actualStringLength = UniCharCount(1)
var result = UCKeyTranslate(layout, keycode, keyaction, modifierKeyState, keyboardType, keyTranslateOptions,
&deadKeyState, maxStringLength, &actualStringLength, &chars)
// Print the results
print("Status: "); println(result)
print("Out:"); println(UnicodeScalar(chars[0]))
println("Done")