ホーム WTL Mobile
UI更新ハンドラ - ダイアログのポップアップメニューアイテム
ドキュメント種別 ATL/WTL に関する文書
最終更新日 2009/07/29
PR
 モーダルダイアログでもモードレスダイアログでも、 ポップアップメニューアイテムの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_VERSIONIDC_BUTTON_VERSIONWM_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メッセージハンドラが用意されており、 そこでポップアップメニューアイテムが更新されます。