ここでは、メッセージと関数を一対一で対応付ける代わりに、一連のメッセージを 1 つのメッセージ ハンドラー関数に対応付ける方法について説明します。
複数のメッセージまたはコントロール通知に対して同一の処理が必要な場合があります。 このような場合は、すべてのメッセージを同じハンドラー関数に対応付けることができます。 メッセージ マップの範囲指定機能を使用すると、指定範囲内のメッセージをまとめて対応付けることができます。以下の種類のメッセージを範囲指定して、1 つのハンドラーに対応付けることができます。
コマンド ID の範囲を指定して次のどちらかに対応付ける。
1 つのコマンド ハンドラー関数
1 つのコマンド更新ハンドラー関数
コントロール ID の範囲を指定して、複数のコントロール通知メッセージを 1 つのメッセージ ハンドラー関数に対応付ける。
ここでは、次のトピックについて説明します。
メッセージ マップ エントリの作成法
ハンドラー関数の宣言
コマンド ID の範囲指定の例
コントロール ID の範囲指定の例
メッセージ マップ エントリの作成法
.CPP ファイルに、次の例のようにメッセージ マップ エントリを追加します。
ON_COMMAND_RANGE(ID_MYCMD_ONE, ID_MYCMD_TEN, &OnDoSomething)
メッセージ マップ エントリは、次の 2 つの要素で構成されます。
メッセージ マップ範囲指定マクロ
マクロ パラメーター
上の最初の 2 つのマクロは、次の 3 つのパラメーターを使用します。
範囲の先頭のコマンド ID
範囲の末尾のコマンド ID
メッセージ ハンドラー関数名
範囲内のコマンド ID は連続している必要があります。
3 番目のマクロでは、ON_CONTROL_RANGE、する追加の最初のパラメーターを受け取り。コントロール通知メッセージなどEN_CHANGE。
ハンドラー関数の宣言
H ファイルで、ハンドラー関数宣言を追加します。 次に示す例では、宣言が追加されています。
public:
afx_msg void OnDoSomething(UINT nID);
1 つのコマンドに対応付けられているハンドラー関数は、通常、パラメーターを取りません。 範囲指定によって複数のメッセージに対応付けたハンドラー関数 (更新ハンドラー関数は例外) では、UINT 型のパラメーター nID を追加し、 このパラメーターを第 1 パラメーターにします。 このパラメーターには、ユーザーが実際に選択したコマンドを指定するときに必要なコマンド ID が格納されています。
更新ハンドラー関数のパラメーター要求の詳細については、次の「コマンド ID の範囲指定の例」を参照してください。
コマンド ID の範囲指定の例
ここでは、範囲指定の使用例として、MFC のサンプル アプリケーション HIERSVR の [ズーム] コマンドについて説明します。 このコマンドは、25% から 300% までの倍率でビューを拡大/縮小します。 HIERSVR のビュー クラスでは、次のようなメッセージ マップ エントリを使って、複数の [ズーム] コマンドを処理します。
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 メッセージ マップ エントリを参照してください。
1 つのコマンドに対応付けられた更新ハンドラー関数は、通常パラメーターとして CCmdUI* 型の pCmdUI を 1 つだけ取ります。 ハンドラー関数とは異なり、メッセージ マップ範囲に対応付けられた更新ハンドラー関数は、パラメーターとして UINT 型の nID を特に必要としません。 ユーザーが実際に選択したコマンドを指定するためのコマンド ID は、CCmdUI オブジェクト内にあります。
コントロール ID の範囲指定の例
範囲指定が可能なもう 1 つのケースは、一定範囲内のコントロール ID に対する一連のコントロール通知メッセージを 1 つのハンドラーに対応付ける場合です。 たとえば、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 );
// ...
}
OnButtonClicked ハンドラーは、BN_CLICKED メッセージが 1 つしかない場合はパラメーターを使用しませんが、 複数のボタンに対応付けられた場合には UINT 型のパラメーターを 1 つ使用します。 このパラメーターによって、BN_CLICKED メッセージを実際に生成したコントロールを特定できます。
例のコードは、典型的なです。渡された値を変換、intメッセージの範囲とこのようなことをアサートします。 確認後、クリックされたボタンに応じて異なった処理を行います。