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

VC++ 菜單開發完全指南:從資源創建到動態控制

     編輯:VC 教學

菜單資源基礎與屬性配置

MFC 自動生成基礎菜單,開發者可在「資源視圖」中可視化編輯。點擊菜單欄左上角圖標可顯示屬性頁,屬性設置不會隨菜單項增減而丟失。注意:ID 灰色不可編輯的項為彈出式菜單,無法直接響應命令。資源 ID 命名規範:IDI_(圖標)、IDC_(控件)、IDM_(菜單命令)。

命令消息路由機制詳解

單個菜單命令的響應順序遵循 MFC 標準路由:

  1. CMainFrame(主框架)
  2. CView 視圖類
  3. CDocument 文檔類
  4. CWinApp 應用程序類

若前者無處理函數,自動傳遞給下一級。AfxMessageBox 可用於非 CWnd 派生類彈出提示;CWnd 派生類直接用 MessageBox。

三類消息類型與映射宏

  • 標準消息:WM_XXX,CWnd 派生類接收。
  • 命令消息:WM_COMMAND,由 ID 識別,CCmdTarget 派生類(文檔、視圖、應用程序類)接收。映射需在頭文件聲明原型,cpp 中用 ON_COMMAND 宏映射並實現處理函數。
  • 通知消息:WM_NOTIFY,CCmdTarget 派生類接收,用 ON_NOTIFY 映射。

命令消息到達順序:MainFrame → View → Doc → View → MainFrame → App。

進階菜單技巧實戰

1. 標記菜單(打勾)

在 CMainFrame::OnCreate 中創建。獲取菜單欄指針 GetMenu() 返回 CMenu*,區分頂級菜單與子菜單。使用 CheckMenuItem 設置勾選狀態。

2. 缺省菜單項(加粗)

SetDefaultItem,如 GetMenu()->GetSubMenu(0)->SetDefaultItem(1, TRUE)。索引含分隔符。每個子菜單僅能有一個缺省項。

3. 圖標菜單項

使用 CMenu::SetMenuItemBitmaps。先 CBitmap::LoadBitmap 載入圖片,再設置標記前後圖像。需注意調整位圖尺寸適配顯示。

4. 禁用/灰化菜單

EnableMenuItem(MF_DISABLED | MF_GRAYED)。關鍵:構造函數中設置 m_bAutoMenuEnable = FALSE,接管菜單更新責任。

5. 移除/更換整個菜單欄

移除:SetMenu(NULL)。更換:局部變量 CMenu 載入新資源 → SetMenu → 必須調用 Detach() 釋放所有權,防止析構時銷毀菜單資源。

命令更新機制

使用 ON_UPDATE_COMMAND_UI 宏,配合 CCmdUI 方法 Enable()、SetCheck() 動態更新狀態。更新順序從第一項到最後一項,**不可用於頂級菜單項**。工具欄按鈕與菜單項通過統一 ID 實現狀態同步,建議最終使用 pCmdUI->m_nID 而非索引訪問。

右鍵彈出菜單實現

在 View 類中處理 WM_RBUTTONDOWN 或 WM_CONTEXTMENU:

  1. 載入菜單資源 LoadMenu,獲取子菜單指針 GetSubMenu(0)。
  2. 坐標轉換:點擊點為客戶區坐標,TrackPopupMenu 需屏幕坐標,必須調用 ClientToScreen。
  3. 調用 TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, x, y, this, NULL),所有者窗口通常為 GetParent()。

動態菜單構建:創建、插入、刪除、響應

  • 創建彈出菜單:CMenu::CreatePopupMenu → AppendMenu(MF_POPUP, (UINT)hMenu, _T("標題")) → Detach()。
  • 插入項目:InsertMenu 指定位置,再 AppendMenu 添加子項。
  • 刪除:DeleteMenu 可刪除項或彈出菜單。
  • 動態項響應:資源頭文件定義 ID → 頭文件聲明 afx_msg void OnXxx() → 映射宏 ON_COMMAND(ID, OnXxx) → 實現函數。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved