MFC 自動生成基礎菜單,開發者可在「資源視圖」中可視化編輯。點擊菜單欄左上角圖標可顯示屬性頁,屬性設置不會隨菜單項增減而丟失。注意:ID 灰色不可編輯的項為彈出式菜單,無法直接響應命令。資源 ID 命名規範:IDI_(圖標)、IDC_(控件)、IDM_(菜單命令)。
單個菜單命令的響應順序遵循 MFC 標準路由:
CMainFrame(主框架)CView 視圖類CDocument 文檔類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。
在 CMainFrame::OnCreate 中創建。獲取菜單欄指針 GetMenu() 返回 CMenu*,區分頂級菜單與子菜單。使用 CheckMenuItem 設置勾選狀態。
SetDefaultItem,如 GetMenu()->GetSubMenu(0)->SetDefaultItem(1, TRUE)。索引含分隔符。每個子菜單僅能有一個缺省項。
使用 CMenu::SetMenuItemBitmaps。先 CBitmap::LoadBitmap 載入圖片,再設置標記前後圖像。需注意調整位圖尺寸適配顯示。
EnableMenuItem(MF_DISABLED | MF_GRAYED)。關鍵:構造函數中設置 m_bAutoMenuEnable = FALSE,接管菜單更新責任。
移除:SetMenu(NULL)。更換:局部變量 CMenu 載入新資源 → SetMenu → 必須調用 Detach() 釋放所有權,防止析構時銷毀菜單資源。
使用 ON_UPDATE_COMMAND_UI 宏,配合 CCmdUI 方法 Enable()、SetCheck() 動態更新狀態。更新順序從第一項到最後一項,**不可用於頂級菜單項**。工具欄按鈕與菜單項通過統一 ID 實現狀態同步,建議最終使用 pCmdUI->m_nID 而非索引訪問。
在 View 類中處理 WM_RBUTTONDOWN 或 WM_CONTEXTMENU:
LoadMenu,獲取子菜單指針 GetSubMenu(0)。TrackPopupMenu 需屏幕坐標,必須調用 ClientToScreen。TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, x, y, this, NULL),所有者窗口通常為 GetParent()。CMenu::CreatePopupMenu → AppendMenu(MF_POPUP, (UINT)hMenu, _T("標題")) → Detach()。InsertMenu 指定位置,再 AppendMenu 添加子項。DeleteMenu 可刪除項或彈出菜單。afx_msg void OnXxx() → 映射宏 ON_COMMAND(ID, OnXxx) → 實現函數。