範囲内のメッセージのハンドラー

このアーティクルでは、1 つのメッセージを 1 つの関数だけマッピングする代わりに、メッセージの範囲を 1 つのメッセージ ハンドラー関数にマップする方法について説明します。

複数のメッセージまたは制御通知をまったく同じ方法で処理する必要がある場合があります。 このような場合は、すべてのメッセージを 1 つのハンドラー関数にマップできます。 メッセージ マップ範囲を使用すると、連続する範囲のメッセージに対してこれを行います。

  • コマンド ID の範囲は、次の場所にマップできます:

    • コマンド ハンドラー関数。

    • コマンド更新ハンドラー関数。

  • コントロール ID の範囲のコントロール通知メッセージをメッセージ ハンドラー関数にマップできます。

この記事では、次のトピックについて説明します。

メッセージ マップ エントリの書き込み

.CPP ファイルに、以下の例のようにメッセージ マップのエントリを追加します。

ON_COMMAND_RANGE(ID_MYCMD_ONE, ID_MYCMD_TEN, &OnDoSomething)

message-map エントリは、次の項目で構成されます:

  • メッセージ マップ範囲マクロ:

  • マクロのパラメーター:

    最初の 2 つのマクロは、次の 3 つのパラメーターを受け取ります。

    • 範囲を開始するコマンド ID

    • 範囲を終了するコマンド ID

    • メッセージ ハンドラー関数の名前

    コマンド ID の範囲は連続している必要があります。

    3 番目のマクロ ON_CONTROL_RANGE は、追加の最初のパラメーターである、EN_CHANGE などのコントロール通知メッセージを受け取ります。

ハンドラー関数の宣言

H ファイルにハンドラー関数宣言を追加します。 次に示すコードは、この外観を示しています。

public:
   afx_msg void OnDoSomething(UINT nID);

単一コマンドのハンドラ関数は、通常、パラメーターを持ちません。 更新ハンドラー関数を除き、メッセージ マップ範囲のハンドラー関数には、UINT 型の追加のパラメーター nID が必要です。 このパラメーターは最初のパラメーターです。 追加のパラメーターは、ユーザーが実際に選択したコマンドを指定するために必要な追加のコマンド ID に対応します。

ハンドラー関数を更新するためのパラメーター要件の詳細は、コマンド ID の範囲の例を参照してください。

コマンド ID の範囲の例

範囲を使用する場合、例の 1 つは、MFC サンプル HIERSVR の Zoom コマンドのようなコマンドを処理する場合です。 このコマンドは、ビューをズームし、通常サイズの 25% から 300% の範囲で拡大縮小します。 HIERSVR のビュー クラスでは、範囲を使用し、次に示すメッセージ マップ エントリを使用して Zoom コマンドを処理します。

ON_COMMAND_RANGE(ID_VIEW_ZOOM25, ID_VIEW_ZOOM300, &OnZoom)

message-map エントリを記述する場合は、次を指定します:

  • 連続する範囲を開始および終了する 2 つのコマンド ID。

    ここでは、これらの ID_VIEW_ZOOM25ID_VIEW_ZOOM300

  • コマンドのハンドラー関数の名前。

    ここでは OnZoom です。

関数宣言は次のようになります:

public:
   afx_msg void OnZoom(UINT nID);

更新ハンドラー関数の場合も同様で、より広く利用される可能性があります。 多くのコマンドに対して ON_UPDATE_COMMAND_UI ハンドラーを書くと、同じコードを何度も書いたり、コピーしたりすることはよくあることです。 解決策は、ON_UPDATE_COMMAND_UI_RANGE マクロを使用して、コマンド ID の範囲を 1 つの更新ハンドラー関数にマップする方法です。 コマンド ID は、連続する範囲を形成する必要があります。 例については、HIERSVR サンプルのビュー クラスの OnUpdateZoom ハンドラーとその ON_UPDATE_COMMAND_UI_RANGE メッセージ マップ エントリを参照してください。

1 つのコマンドの更新ハンドラー関数は、通常、CCmdUI* 型の 1 つのパラメーター pCmdUI を受け取ります。 ハンドラー関数とは異なり、メッセージ マップ範囲の更新ハンドラー関数では、nID (型 UINT) という追加のパラメーターは必要ありません。 ユーザーが実際に選択したコマンドを指定するために必要なコマンド ID は、CCmdUI オブジェクトで見つかりました。

コントロール ID の範囲の例

もう 1 つの興味深いケースは、コントロール ID の範囲に対応するコントロール通知メッセージを 1 つのハンドラにマッピングすることです。 ユーザーが 10 のボタンをクリックできるとします。 10 すべてのボタンを 1 つのハンドラーにマップするには、メッセージ マップ エントリは次のように表示されます。

ON_CONTROL_RANGE(BN_CLICKED, IDC_BUTTON1, IDC_BUTTON10, OnButtonClicked)

メッセージ マップに ON_CONTROL_RANGE マクロを記述する場合は、次を指定します:

  • 特定のコントロール通知メッセージ。

    ここでは BN_CLICKED です。

  • 連続するコントロール範囲に関連付けられているコントロール ID 値。

    ここでは IDC_BUTTON1IDC_BUTTON10 です。

  • メッセージ ハンドラー関数の名前

    ここでは OnButtonClicked です。

ハンドラー関数を記述する場合は、次に示すように、追加の UINT パラメーターを指定します:

void CRangesView::OnButtonClicked(UINT nID)
{
   int nButton = nID - IDC_BUTTON1;
   ASSERT(nButton >= 0 && nButton < 10);
   // ...
}

BN_CLICKED メッセージ 1 つに対する OnButtonClicked ハンドラは、パラメーターを取りません。 ボタンの範囲に対して同じハンドラーが 1 つの UINT を受け取ります。 追加のパラメーターは、BN_CLICKED メッセージの生成に関与した特定のコントロールの識別を可能にします。

例に示したコードは典型的なもので、渡された値をメッセージ範囲内の int に変換し、そのことをアサートします。 その後、クリックされたボタンに応じて、いくつかの異なるアクションを実行できます。

関連項目

メッセージ ハンドラー関数の宣言