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

完美實現真彩自繪選單 CMenuEx:支援 MDI、圖示、動態選單與系統 MRU 清單

     編輯:關於VC++

針對現有自繪選單方案(如 BCMenu、CMenuEx 早期版本)在 MDI 環境下無法處理系統自動插入的選單(如「最近檔案」MRU 清單)、子選單高度不可調、程式碼結構混亂等痛點,本文重構設計 CMenuEx 類別,提供生產級真彩自繪選單完整解決方案。

核心架構優勢

  • 虛擬函數機制:繼承 CMenu,覆寫 MeasureItem/DrawItem,利用 MFC 框架自動呼叫虛擬函數特性,無需手動映射 WM_MEASUREITEM/WM_DRAWITEM。
  • 統一資料結構:MENUITEM 結構完整封裝單一選單項目資訊(文字、ID、圖示索引、子選單指標、啟用狀態等),繪製與測量邏輯完全解耦。
  • 三大靜態輔助函數:
    • MeasureItem(LPMEASUREITEMSTRUCT):統一處理所有選單項目尺寸測量。
    • InitPopupMenu(CMenu*, UINT, BOOL):在 OnInitMenuPopup 中呼叫,自動將系統動態插入的選單項目(如 MRU)轉為 Owner-draw。
    • UpdatePopupMenu():同步更新非自繪建立的彈出選單項目。

MDI 整合步驟

  1. 專案加入 MenuEx.h/.cpp,CMainFrame 宣告兩個 CMenuEx 成員(主選單、文件模板選單)與三組 CImageList(正常/停用/熱點狀態圖示)。
  2. 建立選單圖示索引表 nMenuImageIndex[],對應命令 ID。
  3. InitMenuImage() 載入真彩位圖(ILC_COLOR24)建立三組圖像清單。
  4. InitMainFrameMenu()/InitImageTypeMenu() 分別載入主選單與文件模板選單,設定圖像清單與索引表,回傳 Detach() 後的 HMENU。
  5. 覆寫 OnInitMenuPopup 與 OnMeasureItem,鏈結基類實作後呼叫 CMenuEx 靜態函數。
  6. CXXXApp::InitInstance() 中建立文件模板時,指定 m_hMenuShared = pMainFrame->InitImageTypeMenu();主框架 m_hMenuDefault = pMainFrame->InitMainFrameMenu();最後呼叫 OnUpdateFrameMenu 同步。

關鍵程式碼片段

// 主框架建立選單
HMENU CMainFrame::InitMainFrameMenu() {
    m_menuMainFrame.LoadMenu(IDR_MAINFRAME);
    m_menuMainFrame.SetImageList(&m_imageMenu);
    m_menuMainFrame.SetDisabledImageList(&m_imageMenuDisable);
    m_menuMainFrame.SetHotImageList(&m_imageMenuHot);
    m_menuMainFrame.SetImageIndex(nMenuImageIndex, _countof(nMenuImageIndex));
    return m_menuMainFrame.Detach();
}

// 訊息映射
void CMainFrame::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu) {
    CMDIFrameWnd::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu); // 先讓基類處理(含 MRU 插入)
    CMenuEx::InitPopupMenu(pPopupMenu, nIndex, bSysMenu);        // 再轉為自繪
}
void CMainFrame::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMIS) {
    CMDIFrameWnd::OnMeasureItem(nIDCtl, lpMIS);
    CMenuEx::MeasureItem(lpMIS);
}

圖示載入靈活性

支援兩種模式:

  • 索引表模式:預先定義命令 ID 陣列,呼叫 SetImageIndex 批次指派。
  • 工具列模式:LoadToolBar(CToolBar*) 直接從已建立的真彩工具列同步圖示與索引(工具列真彩建法參考《如何讓工具列顯示 256 色圖像》)。

效果展示

範例程式展示:小圖示選單(索引表模式)、大圖示選單(工具列模式),均呈現 24-bit 真彩色彩、選取漸層、停用灰階、左側圖示區等現代化 UI 風格。

原始碼結構清晰、註解詳盡,歡迎開發者下載修改、整合至專案,打造專業級選單體驗。

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