ホーム ATL/WTL
UI更新ハンドラ - ダイアログのポップアップメニューアイテム
ドキュメント種別 ATL/WTL に関する文書
最終更新日 2007/09/29
PR
 モーダルダイアログでもモードレスダイアログでも、 ポップアップメニューアイテムのUI更新ハンドラを使用できます。

 以下に示すのは、ダイアログにポップアップメニューアイテムのUI更新ハンドラを追加する手順です。 ここでは、ダイアログにメニューバーを追加し、[常に手前に表示]というメニューアイテムが選択されるたびに、 UI更新ハンドラによってメニューアイテムのチェックマークの付加と消去を繰り返すようにします。 なお、ここで示す手順はモーダルダイアログとモードレスダイアログのどちらにも適用できます。


プロジェクトファイル ダウンロード(モーダルダイアログ)
プロジェクトファイル ダウンロード(モードレスダイアログ)

 まず、プロジェクトにメニューリソースを追加し、[ID]、[Caption]、[Prompt]を次のように設定します。

リソース名 ID Caption Prompt
メニュー IDR_MAINFRAME - -
メニューアイテム(トップレベル) - 表示(&V) -
メニューアイテム ID_VIEW_TOPMOST 常に手前に表示(&T) 他のウィンドウよりも常に手前に表示\n常に手前に表示

次に、ダイアログのプロパティを開き、[Menu]にIDR_MAINFRAMEを指定します。 これでダイアログにメニューが追加されます。



 次に、stdafx.hヘッダではCUpdateUIクラステンプレートを使用するためにatlframe.hヘッダをインクルードします。

// stdafx.h
#pragma once

#include <atlbase.h>
#include <atlapp.h>
extern CAppModule _Module;
#include <atlwin.h>

#include <atlcrack.h>
#include <atlmisc.h>
#include <atlframe.h> // CUpdateUIを使用するため
			

 次に、CUpdateUIクラステンプレートをCMainDlgクラスの基底クラスに追加します。

class CMainDlg : public CDialogImpl<CMainDlg>, public CUpdateUI<CMainDlg>
			

 CMainDlgクラスでは、UI更新ハンドラマップとメッセージマップに リソースIDがID_VIEW_TOPMOST用のエントリを追加します。 メッセージマップにはCUpdateUIクラスへのチェインも追加します。

class CMainDlg : public CDialogImpl<CMainDlg>, public CUpdateUI<CMainDlg>
{
public:
    enum { IDD = IDD_MAINDLG };

    // UI更新ハンドラマップ
    BEGIN_UPDATE_UI_MAP(CMainDlg)
        UPDATE_ELEMENT(ID_VIEW_TOPMOST, UPDUI_MENUPOPUP)
    END_UPDATE_UI_MAP()

    // メッセージマップ
    BEGIN_MSG_MAP(CMainDlg)
        MSG_WM_INITDIALOG(OnInitDialog)
        ...
        COMMAND_ID_HANDLER_EX(ID_VIEW_TOPMOST, OnViewTopmost)
        ...
        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){
        ...
        ...

        // [常に手前に表示]メニューアイテムのチェックマーク設定
        UISetCheck(ID_VIEW_TOPMOST, false);

        return TRUE;
    }

    ...
			

 最後に、リソースIDがID_VIEW_TOPMOSTWM_COMMANDメッセージハンドラとしてOnViewTopmost()を追加します。

class CMainDlg : public CDialogImpl<CMainDlg>, public CUpdateUI<CMainDlg>
{
    ...
    ...
    
    void OnViewTopmost(UINT uNotifyCode, int nID, CWindow wndCtl){
        bool bTopmost = !(UIGetState(ID_VIEW_TOPMOST) & UPDUI_CHECKED);
        SetWindowPos(bTopmost ? HWND_TOPMOST : HWND_NOTOPMOST,
            0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
        UISetCheck(ID_VIEW_TOPMOST, bTopmost);
    }

    ...
			

これで、ポップアップメニューアイテム用のUI更新ハンドラが動くようになります。 まず、ダイアログにメニューを追加することで、メニューが表示されるときにWM_INITMENUPOPUPメッセージが ダイアログに送られてくるようになります。 CMainDlgクラスのメッセージマップではWM_INITMENUPOPUPメッセージを処理しないため、 このメッセージはチェイン先のCUpdateUIへ送られます。 CUpdateUIの基底クラスであるCUpdateUIBaseには WM_INITMENUPOPUPメッセージハンドラが用意されており、 そこでポップアップメニューアイテムが更新されます。