6

アプリケーションの任意のウィンドウから主要なイベントを取得し、それらを Unicode として解釈したいと考えています。たとえば、ユーザーがOption-ee (デフォルトで設定された米国英語キーボード) を入力した場合、それを「é」と認識したいと思います。

キープレスイベントをキャプチャして呼び出してみ-[NSEvent characters]ました。ただし、ドキュメントに記載されているように、「このメソッドは、Option-e などの無効なキーに対して空の文字列を返します。」Option-eeと入力すると、 Option-eには何も表示されず、2番目のeにはプレーンな「e」が表示されます。

-[NSEvent keyCode]一連のキーコード (から) を Unicode 文字に結合する方法はありますか?

または、入力された Unicode 文字ごとにイベントを受け取る方法 ( Java の key-typed eventなど)?

4

2 に答える 2

12

一連のキー押下イベントを取得し、それらが入力する Unicode 文字を取得する方法を次に示します。

基本的に、受信したキー押下イベントごとにUCKeyTranslate()を呼び出します。そのdeadKeyState引数を使用してデッド キーを取得し、それを後続の呼び出しに渡します。

例:

  • Option-eのキー押下イベントを受け取ります。
  • UCKeyTranslate()仮想キー コード ( eの場合)、修飾キーの状態 ( Optionの場合)、およびデッド キーの状態を格納する変数を 指定して呼び出します。
    • UCKeyTranslate()空の文字列を出力し、デッド キーの状態を更新します。
  • eのキー押下イベントを受け取ります。
  • UCKeyTranlate()仮想キー コード ( eの場合) とデッド キーの状態を保持する変数を 使用して呼び出します。
    • UCKeyTranslate()「é」を出力します。

サンプルコード (キー押下イベントごとに呼び出す関数):

/**
 * Returns the Unicode characters that would be typed by a key press.
 *
 * @param event A key press event.
 * @param deadKeyState To capture multi-keystroke characters (e.g. Option-E-E for "é"), pass a reference to the same
 *      variable on consecutive calls to this function. Before the first call, you should initialize the variable to 0.
 * @return One or more Unicode characters.
 */
CFStringRef getCharactersForKeyPress(NSEvent *event, UInt32 *deadKeyState)
{
    // http://stackoverflow.com/questions/12547007/convert-key-code-into-key-equivalent-string
    // http://stackoverflow.com/questions/8263618/convert-virtual-key-code-to-unicode-string

    TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
    CFDataRef layoutData = TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData);
    const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout *)CFDataGetBytePtr(layoutData);

    CGEventFlags flags = [event modifierFlags];
    UInt32 modifierKeyState = (flags >> 16) & 0xFF;

    const size_t unicodeStringLength = 4;
    UniChar unicodeString[unicodeStringLength];
    UniCharCount realLength;

    UCKeyTranslate(keyboardLayout,
                   [event keyCode],
                   kUCKeyActionDown,
                   modifierKeyState,
                   LMGetKbdType(),
                   0,
                   deadKeyState,
                   unicodeStringLength,
                   &realLength,
                   unicodeString);
    CFRelease(currentKeyboard);
    return CFStringCreateWithCharacters(kCFAllocatorDefault, unicodeString, realLength);
}
于 2014-03-27T03:28:27.793 に答える