Dato un codice chiave per un tasto premuto senza modificatori, voglio produrre il risultato della pressione del tasto MAIUSC +. Esempio: per una tastiera standard USA < maiuscole> + < periodo> indica>.Come utilizzare UCKeyTranslate
La funzione rilevante è UCKeytranslate, ma ho bisogno di un po 'di aiuto per ottenere i dettagli corretti. Lo snippet seguente è un programma completo pronto per essere eseguito in XCode. L'intento del programma è dato da < periodo> per produrre il carattere>.
Il risultato del programma è:
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 che ottiene il layout sembra funzionare, ma il codice di stato rivela che qualcosa è andato storto. Ma cosa?
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")
EDIT
ho riscritto il frammento seguendo i consigli di Ken Tommaso. Alcuni trucchi da: Graphite è stato utilizzato anche un programma Swift che utilizza i keycode.
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")
Errore "L'uso del tipo non dichiarato 'UCKeyboardLayout'' con questo codice. hai qualche idea su come aggiustarlo? –
I documenti per 10.10.3 dicono che la struttura 'UCKeyboardLayout' è stata rimossa. Hai bisogno di guardare cosa ha sostituito. https://developer.apple.com/library/mac/releasenotes/General/APIDiffsMacOSX10_10_3/modules/CoreServices.html – soegaard
PS: ho provato a cercarlo, ma i documenti per UCKeyboardLayout non menzionano affatto Swift: https: //developer.apple.com/library/mac/documentation/Carbon/Reference/Unicode_Utilities_Ref/#//apple_ref/doc/c_ref/UCKeyboardLayout – soegaard