同一種類の複数のメッセージイベントを一つまとめる方法
ON_UPDATE_COMMAND_UI編




ちょいとメニューを使い出すと、なんだかON_UPDATE_COMMAND_UI関係の関数が増えてきて、 見た目が悪いし、ソースはデバッグしにくくなるしで、ストレスがたまってきます。
そこで今回はそんなうっとおしいON_UPDATE_COMMAND_UIを1カ所で処理させます。

(サンプル:MainFrm.h)
// 生成されたメッセージ マップ関数
protected:
    //{{AFX_MSG(CMainFrame)
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    afx_msg void OnCheckNG();
    afx_msg void OnCheckOK();
    afx_msg void OnAckNakNothiing();
    afx_msg void OnAckSend();
    afx_msg void OnNakSend();
    afx_msg void OnAckNakMsg();
    afx_msg void OnCheckNo();
    afx_msg void OnHealth();
    //}}AFX_MSG
    // メニュー用のコントロールレンジを追加
    afx_msg	void OnMenuUpDate(CCmdUI* pCmdUI);
    DECLARE_MESSAGE_MAP()
};
まずは、クラスウィザードからON_UPDATE_COMMAND_UIの関数を全て削除します。
ただし、ソースコードは消さないように。後でカット&ペーストで使用します。
メニューであれば該当クラスはMainFrmなので、MainFrm.hに新しく呼ばれる関数を 追加します。ここで指定した関数(OnMenuUpDate)に、今までON_UPDATE_COMMAND_UI で処理していたイベントが通るようになるわけです。




(サンプル:MainFrm.cpp)
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
	//{{AFX_MSG_MAP(CMainFrame)
	ON_WM_CREATE()
	ON_COMMAND(Menu_CheckNG, OnCheckNG)
	ON_COMMAND(Menu_CheckOK, OnCheckOK)
	ON_COMMAND(Menu_AckNakNothiing, OnAckNakNothiing)
	ON_COMMAND(Menu_AckSend, OnAckSend)
	ON_COMMAND(Menu_NakSend, OnNakSend)
	ON_COMMAND(Menu_AckNakMsg, OnAckNakMsg)
	ON_COMMAND(Menu_CheckNo, OnCheckNo)
	ON_COMMAND(Menu_Health, OnHealth)
	//}}AFX_MSG_MAP
	// メニュー用のコントロールレンジを追加
	ON_UPDATE_COMMAND_UI_RANGE( Menu_CheckNG, Menu_Conf, OnMenuUpDate )
END_MESSAGE_MAP()
次にMainFrm.cppのメッセージマップを書き替えます。
ON_UPDATE_COMMAND_UI_RANGEはマクロで、最初の引数に連続するコマンドIDの 先頭のコマンドID、2番目の引数に連続するコマンドIDの最後のコマンドID、 3番目の引数には飛び先の関数名を指定します。
コマンドIDがなんのこっちゃ分からんという人はResource.hを見れば分かると 思います。

(サンプル:Resource.h)
#define IDC_FLOWCTRL                    1032
#define Bo_QuickDump                    1033
#define Menu_CheckNG                    32773
#define Menu_CheckOK                    32774
#define Menu_AckSend                    32776
#define Menu_NakSend                    32777
#define Menu_AckNakNothiing             32778
#define Menu_AckNakMsg                  32779
#define Menu_CheckNo                    32780
#define Menu_Health                     32781
#define Menu_Conf                       32782

// Next default values for new objects
// 
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_3D_CONTROLS                1
#define _APS_NEXT_RESOURCE_VALUE        140
#define _APS_NEXT_COMMAND_VALUE         32783
#define _APS_NEXT_CONTROL_VALUE         1034
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif
それでも分からないという人は、C言語の勉強からやり直した方がいいでしょう。
今回はON_UPDATE_COMMAND_UI_RANGEを使いましたが、対象のイベントにより ON_CONTROL_RANGE,ON_COMMANDという別のマクロを使い分けて下さい。




(サンプル:MainFrm.cpp)
void CMainFrame::OnMenuUpDate(CCmdUI* pCmdUI) 
{
	switch( pCmdUI->m_nID )
	{
	case Menu_CheckNG:
		// チェックサムNGのチェック状態を更新する
		if( E_CheckSumOK == D_CHECKSUM_NG )
		{
			pCmdUI->SetCheck( 1 );
		}
		else
		{
			pCmdUI->SetCheck( 0 );
		}

		// チェックサムNGを選択可能状態にする
		pCmdUI->Enable(TRUE);

		break;

	case Menu_CheckOK:
後は、関数本体を作成して、内容は元のON_UPDATE_COMMAND_UI_RANGEイベントでの処理を 使えば完了です。
ちょっと厄介なのが、どのメニュー項目に対するイベントかの判定ですが、サンプルの ように、パラメータの変数からメンバ変数m_nIDを参照することで取得できます。
元のON_UPDATE_COMMAND_UI_RANGEを削除し忘れないように。




N総研ソフトウェア開発部のTOPに戻る。

このページに関するご意見・質問は
ドンタコスN村 E-mail:wnaka@coco.ned.co.jp
まで送信してください。