モーダルダイアログでもモードレスダイアログでも、
ポップアップメニューアイテムのUI更新ハンドラを使用できます。
以下に示すのは、ダイアログにポップアップメニューアイテムのUI更新ハンドラを追加する手順です。
ここでは、ダイアログにメニューバーを追加し、[バージョン情報]というメニューアイテムが選択されるたびに、
UI更新ハンドラによってメニューアイテムのチェックマークの付加と消去を繰り返すようにします。
チェックマークが付加されている場合のみ[バージョン情報を表示する]ボタンを押すとメッセージボックスを表示します。
なお、ここで示す手順はモーダルダイアログとモードレスダイアログのどちらにも適用できます。
まず、プロジェクトにメニューリソースを追加し、[ID]と[Caption]を次のように設定します。
| リソース名 |
ID |
Caption |
| メニュー |
IDR_MAINFRAME |
- |
| メニューアイテム(トップレベル) |
IDOK |
OK |
| メニューアイテム(トップレベル) |
- |
メニュー |
| メニューアイテム |
ID_RMENU_VERSION |
バージョン情報 |

次に、ダイアログにボタンコントロールを配置し、[ID]と[Caption]を次のように設定します。
| リソース名 |
ID |
Caption |
| ボタン |
IDC_BUTTON_VERSION |
バージョン情報を表示する |

次に、stdafx.hヘッダではCUpdateUIクラステンプレートを使用するためにatlframe.hヘッダをインクルードします。
// stdafx.h
#pragma once
#define WINVER _WIN32_WCE
#define _SECURE_ATL 1
#include <atlbase.h>
#include <atlapp.h>
extern CAppModule _Module;
#include <atlwin.h>
#include <aygshell.h>
#pragma comment(lib, "aygshell.lib")
#include <atlcrack.h>
#include <atlmisc.h>
#include <atlframe.h> // CUpdateUIを使用するため
|
次に、CUpdateUIクラステンプレートをCMainDlgクラスの基底クラスに追加します。
class CMainDlg : public CDialogImpl<CMainDlg>, public CUpdateUI<CMainDlg>
|
CMainDlgクラスでは、メニューアイテムの状態を更新するために、
UI更新ハンドラマップにリソースIDがID_RMENU_VERSIONのエントリを追加します。
また、メッセージマップにはメニューアイテム用にリソースIDがID_RMENU_VERSIONのエントリを追加し、
ボタン用にリソースIDがIDC_BUTTON_VERSIONのエントリを追加します。
さらに、CUpdateUIクラスへのチェインも追加します。
class CMainDlg : public CDialogImpl<CMainDlg>, public CUpdateUI<CMainDlg>
{
public:
enum { IDD = IDD_MAINDLG };
CMenu menu;
// UI更新ハンドラマップ
BEGIN_UPDATE_UI_MAP(CMainDlg)
UPDATE_ELEMENT(ID_RMENU_VERSION, UPDUI_MENUPOPUP)
END_UPDATE_UI_MAP()
// メッセージマップ
BEGIN_MSG_MAP(CMainDlg)
MSG_WM_INITDIALOG(OnInitDialog)
...
COMMAND_ID_HANDLER_EX(ID_RMENU_VERSION, OnRMenuVersion)
COMMAND_ID_HANDLER_EX(IDC_BUTTON_VERSION, OnButtonVersion)
...
CHAIN_MSG_MAP(CUpdateUI<CMainDlg>) // CUpdateUIへのチェイン
END_MSG_MAP()
...
|
次に、WM_INITDIALOGメッセージハンドラではメニューバーを作成し、
UISetCheck()を呼び出して[バージョン情報]メニューアイテムのチェックマークを設定します。
class CMainDlg : public CDialogImpl<CMainDlg>, public CUpdateUI<CMainDlg>
{
...
...
BOOL OnInitDialog(CWindow wndFocus, LPARAM lInitParam){
SHINITDLGINFO shidi = { SHIDIM_FLAGS, m_hWnd,
SHIDIF_SIZEDLGFULLSCREEN | SHIDIF_DONEBUTTON };
::SHInitDialog(&shidi);
// メニューリソースを読み込む
menu.LoadMenu(IDR_MAINFRAME);
// メニューバー作成
SHMENUBARINFO mbi = {0};
mbi.cbSize = sizeof(SHMENUBARINFO);
mbi.hwndParent = m_hWnd;
mbi.dwFlags = SHCMBF_HMENU;
mbi.nToolBarId = (UINT)menu.m_hMenu;
mbi.hInstRes = ModuleHelper::GetResourceInstance();
::SHCreateMenuBar(&mbi);
// [バージョン情報]メニューアイテムのチェックマーク設定
UISetCheck(ID_RMENU_VERSION, true);
...
...
}
...
|
最後に、リソースIDがID_RMENU_VERSIONとIDC_BUTTON_VERSIONのWM_COMMANDメッセージハンドラとして、
OnRMenuVersion()とOnButtonVersion()を追加します。
OnRMenuVersion()ではチェックマークを設定し、
OnButtonVersion()ではチェックマークの状態に応じてメッセージボックスを表示します。
class CMainDlg : public CDialogImpl<CMainDlg>, public CUpdateUI<CMainDlg>
{
...
...
void OnRMenuVersion(UINT uNotifyCode, int nID, CWindow wndCtl){
bool bCheck = (UIGetState(ID_RMENU_VERSION) & UPDUI_CHECKED) != UPDUI_CHECKED;
UISetCheck(ID_RMENU_VERSION, bCheck);
}
void OnButtonVersion(UINT uNotifyCode, int nID, CWindow wndCtl){
if((UIGetState(ID_RMENU_VERSION) & UPDUI_CHECKED) == UPDUI_CHECKED){
MessageBox(_T("SampleProject"));
}
}
...
|
これで、ポップアップメニューアイテム用のUI更新ハンドラが動くようになります。
まず、ダイアログにメニューを追加することで、メニューが表示されるときにWM_INITMENUPOPUPメッセージが
ダイアログに送られてくるようになります。
CMainDlgクラスのメッセージマップではWM_INITMENUPOPUPメッセージを処理しないため、
このメッセージはチェイン先のCUpdateUIへ送られます。
CUpdateUIの基底クラスであるCUpdateUIBaseには
WM_INITMENUPOPUPメッセージハンドラが用意されており、
そこでポップアップメニューアイテムが更新されます。
|