2 Stimmen

Wie verwende ich CGEventKeyboardSetUnicodeString mit mehreren Zeichen?

Ich versuche, Event-Taps zu verwenden, um ein OS X-Programm zu erstellen, das auf Jiddisch in Transliteration getippt wird und das Ergebnis in hebräischen Zeichen veröffentlicht. Ich habe ein sehr kurzes Programm erstellt, um eine Sache zu testen, die ich tun müsste: http://pastie.org/791398

Derzeit ersetzt das Programm erfolgreich jedes getippte 'q' durch 'w':

if(inputString[0] == 'q') { inputString[0] = 'w'; }

Aber wie postet man einen String mit mehr als einem Zeichen? Wenn jemand beispielsweise 'sh' eingibt, müssten Sie wahrscheinlich einen Backspace posten (um das Zeichen zu löschen, das nur für 's' gepostet wurde) und dann das Zeichen posten, das 'sh' entspricht. Dieser Code führt jedoch nur dazu, dass ein Backspace gepostet wird:

else if(inputString[0] == 'm') { inputString[0] = '\b'; inputString[1] = 'n'; }

Es tut mir leid, wenn dies grundlegende Fragen sind; Ich habe alle Dokumentationen gelesen, die ich finden konnte, aber vielleicht habe ich nicht alles verstanden. Es ist auch möglich, dass ich dabei völlig falsch vorgehe.

2voto

Nicholas Riley Punkte 41936

Idealerweise sollten Sie eine Eingabemethode anstelle eines Programms mit Ereignistaps verwenden, höchstwahrscheinlich mit Input Method Kit, wenn Sie keine Unterstützung für vor 10.5 benötigen. Die Verwendung von Ereignistaps für diesen Zweck ist grundsätzlich keine gute Idee, weil der Benutzer mit der Maus sowie mit der Tastatur ändern kann, wo er/sie tippt. Wenn der Benutzer also ein "s" in ein Textfeld tippt, gefolgt von einem "h" in einem anderen, könnten Sie den Unterschied nicht feststellen.

Davon abgesehen, hier ist eine direkte Antwort auf Ihre Frage.

Der String wird auf Längenzählung überprüft, daher können Sie nicht einfach die eingehende Länge (1) angeben; das zweite Zeichen wird ignoriert. Die meisten Anwendungen möchten jedoch auch nicht mehr als ein einziges Zeichen pro Ereignis erhalten, daher werden sie einfach die übrigen Zeichen verwerfen. (Terminal ist eine bemerkenswerte Ausnahme.)

Also können Sie einfach ein zweites Ereignis mit dem zweiten Zeichen senden.

else if(inputString[0] == 'm') {
  inputString[0] = 'n';
  CGEventKeyboardSetUnicodeString(event, 1, inputString);
  CGEventPost(kCGSessionEventTap, event);
  inputString[0] = '\b';
}

In dem allgemeinen Fall (Simulation von > 2 Tastendrücken) müssen Sie für jedes Zeichen, das Sie einfügen möchten, ein Ereignis erstellen. Dieser Beitrag in der Mailingliste enthält ein einfaches Beispiel.

0 Stimmen

Vielen Dank! Das ist wirklich nützlich zu wissen -- und du hast recht, dass ich eine Eingabemethode mit IMKit erstellen sollte. (Tatsächlich ist es einfacher, ein Eingabemethoden-Framework wie MacUIM zu verwenden: code.google.com/p/macuim)

1voto

Moose Punkte 2436

So sende ich einen String an den ersten Responder (Vordergrundanwendung)

// 1 - Die Länge des Strings in Byte erhalten.
NSUInteger l = [string lengthOfBytesUsingEncoding: NSUTF16StringEncoding];

// 2 - Bytes für Unicode-Zeichen erhalten
UniChar *uc = malloc(l);
[string getBytes:uc maxLength:l usedLength:NULL encoding:NSUTF16StringEncoding options:0 range: NSMakeRange(0, l) remainingRange:NULL];

// 3 - Ein leeres Tastaturereignis erstellen und Unicode-String setzen
CGEventRef tap = CGEventCreateKeyboardEvent(NULL,0, YES);
CGEventKeyboardSetUnicodeString(tap, string.length, uc);

// 4 - Ereignis senden und aufräumen
CGEventPost(kCGSessionEventTap, tap);
CFRelease(tap);
free(uc);

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X