この記事では、メッセージの範囲を 1 つのメッセージ ハンドラー関数にマップする方法について説明します (1 つのメッセージを 1 つの関数にのみマッピングするのではなく)。
まったく同じ方法で複数のメッセージを処理したり、通知を制御したりする必要がある場合があります。 このような場合は、すべてのメッセージを 1 つのハンドラー関数にマップできます。 メッセージ マップ範囲を使用すると、連続したメッセージ範囲に対してこれを行うことができます。
コマンド ID の範囲は、次の場所にマップできます。
コマンド ハンドラー関数。
コマンド更新ハンドラー関数。
コントロール ID の範囲のコントロール通知メッセージをメッセージ ハンドラー関数にマップできます。
この記事で取り上げるトピックは次のとおりです。
Message-Map エントリの書き込み
の。次の例に示すように、CPP ファイルにメッセージ マップ エントリを追加します。
ON_COMMAND_RANGE(ID_MYCMD_ONE, ID_MYCMD_TEN, &OnDoSomething)
メッセージ マップ エントリは、次の項目で構成されます。
メッセージ マップ範囲マクロ:
マクロのパラメーター:
最初の 2 つのマクロは、次の 3 つのパラメーターを受け取ります。
範囲を開始するコマンド ID
範囲を終了するコマンド ID
メッセージ ハンドラー関数の名前
コマンド ID の範囲は連続している必要があります。
3 番目のマクロ
ON_CONTROL_RANGE
は、 EN_CHANGEなどのコントロール通知メッセージという追加の最初のパラメーターを受け取ります。
ハンドラー関数の宣言
にハンドラー関数宣言を追加します。H ファイル。 次のコードは、次に示すように、この方法を示しています。
public:
afx_msg void OnDoSomething(UINT nID);
通常、1 つのコマンドのハンドラー関数はパラメーターを受け取っていません。 更新ハンドラー関数を除き、メッセージ マップ範囲のハンドラー関数には、UINT 型の追加パラメーター nID が必要です。 このパラメーターは最初のパラメーターです。 追加パラメーターは、ユーザーが実際に選択したコマンドを指定するために必要な追加のコマンド ID に対応します。
ハンドラー関数を更新するためのパラメーター要件の詳細については、「コマンド ID の範囲の例」を参照してください。
コマンド ID の範囲の例
範囲を使用する場合は、MFC サンプル HIERSVR の Zoom コマンドのようなコマンドを処理する例があります。 このコマンドを実行すると、ビューがズームされ、通常のサイズの 25% から 300% の間で拡大縮小されます。 HIERSVR のビュー クラスは、範囲を使用して、次に似たメッセージ マップ エントリで Zoom コマンドを処理します。
ON_COMMAND_RANGE(ID_VIEW_ZOOM25, ID_VIEW_ZOOM300, &OnZoom)
メッセージ マップ エントリを記述するときは、次のように指定します。
連続する範囲の先頭と末尾の 2 つのコマンド ID。
ここでは、 ID_VIEW_ZOOM25 と ID_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
メッセージ マップ エントリを参照してください。
単一コマンドの更新ハンドラー関数は、通常、CCmdUI*
型の 1 つのパラメーター pCmdUI を受け取ります。 ハンドラー関数とは異なり、メッセージ マップ範囲の更新ハンドラー関数には、UINT 型の追加パラメーター nID は必要ありません。 ユーザーが実際に選択したコマンドを指定するために必要なコマンド 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_BUTTON1 と IDC_BUTTON10です。
メッセージ ハンドラー関数の名前。
ここでは、
OnButtonClicked
。
ハンドラー関数を記述するときは、次に示すように、追加の UINT パラメーターを指定します。
void CRangesView::OnButtonClicked(UINT nID)
{
int nButton = nID - IDC_BUTTON1;
ASSERT(nButton >= 0 && nButton < 10);
// ...
}
1 つのBN_CLICKED メッセージのOnButtonClicked
ハンドラーはパラメーターを受け取っていません。 ボタンの範囲に対して同じハンドラーが 1 つの UINT を受け取ります。 追加のパラメーターを使用すると、 BN_CLICKED メッセージの生成を担当する特定のコントロールを識別できます。
この例に示すコードは一般的です。メッセージ範囲内の int
に渡された値を変換し、これが当てはまることをアサートします。 その後、クリックされたボタンに応じて、いくつかの異なるアクションを実行できます。