次の方法で共有


キーボード入力 (はじめに Win32 および C++ を使用)

キーボードは、次のようないくつかの異なる種類の入力に使用されます。

  • 文字入力。 ユーザーがドキュメントまたは編集ボックスに入力するテキスト。
  • キーボード ショートカット。 アプリケーション関数を呼び出すキー ストローク。たとえば、Ctrl + O キーを押してファイルを開きます。
  • システム コマンド。 システム関数を呼び出すキー ストローク。たとえば、ウィンドウを切り替えるには Alt + TAB キーを押します。

キーボード入力について考える場合は、キー ストロークが文字と同じではないことに注意することが重要です。 たとえば、A キーを押すと、次のいずれかの文字が発生する可能性があります。

  • a
  • A
  • á (キーボードが分音記号の組み合わせをサポートしている場合)

さらに、Alt キーを押すと、A キーを押すと Alt + A が生成されます。これは、システムが文字としてではなく、システム コマンドとして扱います。

キー コード

キーを押すと、ハードウェアによって スキャン コードが生成されます。 スキャン コードはキーボードによって異なり、キーアップ イベントとキーダウン イベントには個別のスキャン コードがあります。 スキャン コードはほとんど気にしません。 キーボード ドライバーは、スキャン コードを 仮想キー コードに変換します。 仮想キー コードは、デバイスに依存しません。 キーボードで A キーを押すと、同じ仮想キー コードが生成されます。

一般に、仮想キー コードは、ASCII コードやその他の文字エンコード標準には対応していません。 これは、同じキーが異なる文字 (a、A、á) を生成し、関数キーなどの一部のキーが文字に対応していないため、考えると明らかです。

とは言え、次の仮想キー コードは ASCII と同等のコードにマップされます。

  • 0 ~ 9 キー = ASCII '0' – '9' (0x30 – 0x39)
  • A ~ Z キー = ASCII 'A' – 'Z' (0x41 – 0x5A)

一部の点では、仮想キー コードを文字として考えるべきではないため、このマッピングは残念です。説明した理由からです。

ヘッダー ファイル WinUser.h は、ほとんどの仮想キー コードの定数を定義します。 たとえば、←キーの仮想キー コードは VK_LEFT (0x25) です。 仮想キー コードの完全な一覧については、「 仮想キー コード」を参照してください。 ASCII 値に一致する仮想キー コードに対して定数が定義されていません。 たとえば、A キーの仮想キー コードは0x41ですが、 VK_Aという名前の定数はありません。 代わりに、数値を使用してください。

メッセージのKey-DownとKey-Up

キーを押すと、キーボード フォーカスのあるウィンドウに次のいずれかのメッセージが表示されます。

WM_SYSKEYDOWN メッセージは、システム コマンドを呼び出すキー ストロークであるシステム キーを示します。 システム キーには、次の 2 種類があります。

  • Alt + 任意のキー
  • F10

F10 キーを押して、ウィンドウのメニュー バーをアクティブにします。 さまざまな Alt キーの組み合わせによって、システム コマンドが呼び出されます。 たとえば、Alt + TAB キーを押して新しいウィンドウに切り替えます。 また、ウィンドウにメニューがある場合は、Alt キーを使用してメニュー項目をアクティブ化できます。 一部の Alt キーの組み合わせでは何も行われません。

他のすべてのキー ストロークは非システム キーと見なされ、 WM_KEYDOWN メッセージが生成されます。 これには、F10 以外のファンクション キーが含まれます。

キーを解放すると、対応するキーアップ メッセージが送信されます。

キーボードの繰り返し機能を開始するのに十分な長さがあるキーを押すと、システムは複数のキーダウン メッセージを送信し、その後に 1 つのキーアップ メッセージを送信します。

これまでに説明した 4 つのキーボード メッセージすべてで、 wParam パラメーターにはキーの仮想キー コードが含まれています。 lParam パラメーターには、32 ビットにパックされたその他の情報が含まれています。 通常、 lParam の情報は必要ありません。 便利なフラグの 1 つは、ビット 30 である "前のキー状態" フラグです。これは、キーダウン メッセージを繰り返す場合は 1 に設定されます。

名前が示すように、システム キー ストロークは主にオペレーティング システムで使用することを目的としています。 WM_SYSKEYDOWN メッセージをインターセプトした場合は、後で DefWindowProc を呼び出します。 それ以外の場合は、オペレーティング システムによるコマンドの処理をブロックします。

文字メッセージ

キー ストロークは、モジュール 1 で最初に見た TranslateMessage 関数によって文字に変換されます。 この関数は、キーダウン メッセージを調べて、それらを文字に変換します。 TranslateMessage 関数は、生成される文字ごとに、WM_CHARまたはWM_SYSCHARメッセージをウィンドウのメッセージ キューに配置します。 メッセージの wParam パラメーターには UTF-16 文字が含まれています。

ご想像のとおり、 WM_CHAR メッセージは WM_KEYDOWN メッセージから生成され、 WM_SYSCHAR メッセージは WM_SYSKEYDOWN メッセージから生成されます。 たとえば、ユーザーが Shift キーを押し、その後に A キーを押すとします。 標準のキーボード レイアウトを想定すると、次の一連のメッセージが表示されます。

WM_KEYDOWN: Shift
WM_KEYDOWN: A
WM_CHAR: 'A'

一方、Alt + P の組み合わせによって次の結果が生成されます。

WM_SYSKEYDOWN: VK_MENU
WM_SYSKEYDOWN: 0x50
WM_SYSCHAR: 'p'
WM_SYSKEYUP: 0x50
WM_KEYUP: VK_MENU

(Alt キーの仮想キー コードは、歴史的な理由からVK_MENUという名前です)。

WM_SYSCHAR メッセージはシステム文字を示します。 WM_SYSKEYDOWNと同様に、通常、このメッセージを DefWindowProc に直接渡す必要があります。 それ以外の場合は、標準のシステム コマンドに干渉する可能性があります。 特に、 WM_SYSCHAR はユーザーが入力したテキストとして扱わないでください。

WM_CHAR メッセージは、通常、文字入力と見なされます。 文字のデータ型は、UTF-16 Unicode 文字を表す wchar_t。 文字入力には、特に米国の外部で一般的に使用されるキーボード レイアウトでは、ASCII 範囲外の文字を含めることができます。 地域のキーボードをインストールし、スクリーン キーボード機能を使用して、さまざまなキーボード レイアウトを試すことができます。

ユーザーは、入力方法エディター (IME) をインストールして、日本語の文字などの複雑なスクリプトを標準キーボードで入力することもできます。 たとえば、日本語の IME を使用してカタカナ文字カ (ka) を入力すると、次のメッセージが表示されることがあります。

WM_KEYDOWN: VK_PROCESSKEY (IME PROCESS キー)
WM_KEYUP: 0x4B
WM_KEYDOWN: VK_PROCESSKEY
WM_KEYUP: 0x41
WM_KEYDOWN: VK_PROCESSKEY
WM_CHAR: カ
WM_KEYUP: VK_RETURN

一部の Ctrl キーの組み合わせは、ASCII コントロール文字に変換されます。 たとえば、Ctrl + A は ASCII Ctrl-A (SOH) 文字 (ASCII 値0x01) に変換されます。 テキスト入力の場合は、通常、制御文字を除外する必要があります。 また、 WM_CHAR を使用してキーボード ショートカットを実装しないようにします。 代わりに、 メッセージWM_KEYDOWN 使用します。またはさらに良い場合は、アクセラレータ テーブルを使用します。 アクセラレータ テーブルについては、次のトピック「 Accelerator Tables」で説明します

次のコードは、デバッガーのメインキーボード メッセージを表示します。 さまざまなキーストロークの組み合わせで再生して、生成されるメッセージを確認してください。

注意

必ず wchar.h を含めるか、それ以外のswprintf_sは未定義になります。

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    wchar_t msg[32];
    switch (uMsg)
    {
    case WM_SYSKEYDOWN:
        swprintf_s(msg, L"WM_SYSKEYDOWN: 0x%x\n", wParam);
        OutputDebugString(msg);
        break;

    case WM_SYSCHAR:
        swprintf_s(msg, L"WM_SYSCHAR: %c\n", (wchar_t)wParam);
        OutputDebugString(msg);
        break;

    case WM_SYSKEYUP:
        swprintf_s(msg, L"WM_SYSKEYUP: 0x%x\n", wParam);
        OutputDebugString(msg);
        break;

    case WM_KEYDOWN:
        swprintf_s(msg, L"WM_KEYDOWN: 0x%x\n", wParam);
        OutputDebugString(msg);
        break;

    case WM_KEYUP:
        swprintf_s(msg, L"WM_KEYUP: 0x%x\n", wParam);
        OutputDebugString(msg);
        break;

    case WM_CHAR:
        swprintf_s(msg, L"WM_CHAR: %c\n", (wchar_t)wParam);
        OutputDebugString(msg);
        break;

    /* Handle other messages (not shown) */

    }
    return DefWindowProc(m_hwnd, uMsg, wParam, lParam);
}

その他のキーボード メッセージ

他の一部のキーボード メッセージは、ほとんどのアプリケーションで無視しても問題ありません。

  • WM_DEADCHAR メッセージは、分音記号などの結合キーに対して送信されます。 たとえば、スペイン語のキーボードでは、アクセント (') に続けて E を入力すると、文字 é が生成されます。 アクセント記号の WM_DEADCHAR が送信されます。
  • WM_UNICHAR メッセージは廃止されました。 これにより、ANSI プログラムは Unicode 文字入力を受け取ることができます。
  • WM_IME_CHAR文字は、IME がキーストローク シーケンスを文字に変換するときに送信されます。 通常の WM_CHAR メッセージに加えて送信されます。

キーボードの状態

キーボード メッセージはイベント ドリブンです。 つまり、キーを押すなど、何か興味深いことが起こるとメッセージが表示され、メッセージは何が起こったかを示します。 ただし、 GetKeyState 関数を呼び出すことで、いつでもキーの状態をテストすることもできます。

たとえば、マウスの左クリック + Alt キーの組み合わせを検出する方法を考えてみましょう。 Alt キーの状態を追跡するには、キー ストローク メッセージをリッスンし、フラグを格納しますが、 GetKeyState を使用すると問題が解決します。 WM_LBUTTONDOWN メッセージが表示されたら、次のように GetKeyState を呼び出します。

if (GetKeyState(VK_MENU) & 0x8000)
{
    // ALT key is down.
}

GetKeyState メッセージは、仮想キー コードを入力として受け取り、ビット フラグのセット (実際には 2 つのフラグのみ) を返します。 0x8000値には、キーが現在押されているかどうかをテストするビット フラグが含まれています。

ほとんどのキーボードには、左と右の 2 つの Alt キーがあります。 前の例では、どちらかが押されたかどうかをテストします。 GetKeyState を使用して、Alt キー、Shift キー、または Ctrl キーの左右のインスタンスを区別することもできます。 たとえば、次のコードでは、右の Alt キーが押されているかどうかをテストします。

if (GetKeyState(VK_RMENU) & 0x8000)
{
    // Right ALT key is down.
}

GetKeyState 関数は、仮想キーボードの状態を報告するため、興味深いです。 この仮想状態はメッセージ キューの内容に基づいており、キューからメッセージを削除すると更新されます。 プログラムでウィンドウ メッセージが処理されると、GetKeyState によって、各メッセージがキューに登録された時点でキーボードのスナップショットが提供されます。 たとえば、キューの最後のメッセージが WM_LBUTTONDOWNされた場合、 GetKeyState は、ユーザーがマウス ボタンをクリックした時点でキーボードの状態を報告します。

GetKeyState はメッセージ キューに基づいているため、別のプログラムに送信されたキーボード入力も無視されます。 ユーザーが別のプログラムに切り替える場合、そのプログラムに送信されるキーの押下は 、GetKeyState によって無視されます。 キーボードの即時の物理的な状態を本当に知りたい場合は、 GetAsyncKeyState という関数があります。 ただし、ほとんどの UI コードでは、正しい関数は GetKeyState です

次へ

アクセラレータ テーブル