範囲内のメッセージのハンドラ
更新 : 2007 年 11 月
ここでは、メッセージと関数を一対一で対応付ける代わりに、一連のメッセージを 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 はもう 1 つパラメータを使用します (これが第 1 パラメータになります)。このパラメータで、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 値に変換してから指定範囲に収まっているかどうかを確認しています。確認後、クリックされたボタンに応じて異なった処理を行います。