首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

MFC 訊息映射實現動態選單:ON_UPDATE_COMMAND_UI 與 CCmdUI 完全指南

     編輯:VC 教學

為何選擇訊息映射而非 GetMenu()?

傳統 GetMenu()->AppendMenu/ModifyMenu 程式碼分散、難維護。MFC ON_UPDATE_COMMAND_UI 機制在選單即將顯示前自動呼叫更新處理函數,集中管理啟用/禁用、文字、勾選狀態,邏輯清晰。

核心機制

  • ON_UPDATE_COMMAND_UI(ID, Handler) 將選單項 ID 與更新函數綁定
  • 處理函數原型:afx_msg void Handler(CCmdUI* pCmdUI);
  • CCmdUI 提供:Enable()、SetText()、SetCheck()、SetRadio()
  • 觸發時機:使用者點選選單列、熱鍵、快速鍵選中同層級任一項目

彈出式選單特殊處理

彈出選單本身無 ID,無法直接映射。MFC 規定:彈出選單第一個項目的更新函數會被呼叫兩次:

  1. 繪製彈出選單項目時 → pCmdUI->m_pSubMenu == NULL
  2. 繪製父選單列上的彈出選單標題時 → pCmdUI->m_pSubMenu != NULL (此時需手動啟用/禁用整個彈出選單)

完整範例:巢狀選單動態狀態

資源結構

Test Menu
  Item One        ID_ITEM_ONE
  Item Two        ID_ITEM_TWO
  Popup ►
    Popup One     ID_POPUP_ONE
    Popup Two     ID_POPUP_TWO

類別宣告

class CMyDoc : public CDocument {
    BOOL m_bItemOne, m_bItemTwo, m_bPopupOne, m_bPopupTwo;
    afx_msg void OnUpdateItemOne(CCmdUI*);
    afx_msg void OnUpdateItemTwo(CCmdUI*);
    afx_msg void OnUpdatePopupOne(CCmdUI*);
    afx_msg void OnUpdatePopupTwo(CCmdUI*);
    DECLARE_MESSAGE_MAP()
};

訊息映射

BEGIN_MESSAGE_MAP(CMyDoc, CDocument)
    ON_UPDATE_COMMAND_UI(ID_ITEM_ONE,   OnUpdateItemOne)
    ON_UPDATE_COMMAND_UI(ID_ITEM_TWO,   OnUpdateItemTwo)
    ON_UPDATE_COMMAND_UI(ID_POPUP_ONE,  OnUpdatePopupOne)
    ON_UPDATE_COMMAND_UI(ID_POPUP_TWO,  OnUpdatePopupTwo)
END_MESSAGE_MAP()

處理函數實作

void CMyDoc::OnUpdateItemOne(CCmdUI* p) {
    p->Enable(m_bItemOne);
    p->SetText(m_bItemOne ? _T("Item One") : _T("Item One (Disabled)"));
}
void CMyDoc::OnUpdateItemTwo(CCmdUI* p) {
    p->Enable(m_bItemTwo);
    p->SetText(m_bItemTwo ? _T("Item Two") : _T("Item Two (Disabled)"));
}
void CMyDoc::OnUpdatePopupOne(CCmdUI* p) {
    if(p->m_pSubMenu) { // 父選單列繪製 Popup 標題
        BOOL bEnable = m_bPopupOne || m_bPopupTwo;
        p->m_pMenu->EnableMenuItem(p->m_nIndex, MF_BYPOSITION | (bEnable ? MF_ENABLED : MF_DISABLED|MF_GRAYED));
        return;
    }
    p->Enable(m_bPopupOne); // 彈出選單內繪製 Popup One 項目
}
void CMyDoc::OnUpdatePopupTwo(CCmdUI* p) {
    p->Enable(m_bPopupTwo);
}

進階技巧

  • 工具列按鈕同樣走此機制,ID 一致即可同步狀態
  • 動態文字 (如顯示目前檔案名) 直接在 Handler 中 SetText
  • 複雜邏輯可集中在 UpdateUIState() 供所有 Handler 呼叫

結語

善用 ON_UPDATE_COMMAND_UI 讓選單/工具列狀態與資料模型即時同步,是 MFC 專業級 UI 開發的標誌性技能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved