Windows 應用程式普遍使用下拉式選單提供功能入口。靜態選單在編譯後固定不變,但實際開發中常需依使用者權限、設定或情境動態調整選單項目。本文以 MFC SDI 專案為例,詳細說明如何在執行期建立、切換、新增、插入與修改選單項目。
mymenu。IDR_MENU1。IDD_DIALOG1。ID_CLEAR、ID_GOONE、ID_GOTWO、ID_ADD、ID_ADDITEM、ID_EDIT。CChangeMenu,並為六個按鈕加入預設處理函式。IDR_MAINFRAME 選單加入新項目,ID 為 ID_SET,標題「彈出設定對話框」。OnSet():void CMainFrame::OnSet()
{
CChangeMenu dlg;
dlg.DoModal();
}
記得在 MainFrm.cpp 頂端加入 #include "ChangeMenu.h"。
在 CChangeMenu 中實作六個按鈕的處理邏輯:
void CChangeMenu::OnClear()
{
AfxGetMainWnd()->SetMenu(NULL);
AfxGetMainWnd()->DrawMenuBar();
}
void CChangeMenu::OnGoone()
{
if (!menu1) // menu1 為 CMenu 成員變數
{
menu1.LoadMenu(IDR_MENU1);
AfxGetMainWnd()->SetMenu(&menu1);
AfxGetMainWnd()->DrawMenuBar();
menu1.Detach(); // 避免析構時銷毀 HMENU
}
}
void CChangeMenu::OnGotwo()
{
if (!menu2) // menu2 為 CMenu 成員變數
{
menu2.LoadMenu(IDR_MAINFRAME);
AfxGetMainWnd()->SetMenu(&menu2);
AfxGetMainWnd()->DrawMenuBar();
menu2.Detach();
}
}
void CChangeMenu::OnAdd()
{
static int x = 400; // 命令 ID 從 400 起始遞增
AfxGetMainWnd()->GetMenu()->AppendMenu(MF_STRING, x, "mynew");
AfxGetMainWnd()->DrawMenuBar();
x++;
}
void CChangeMenu::OnAdditem()
{
static int y = 500;
AfxGetMainWnd()->GetMenu()->GetSubMenu(0)->InsertMenu(1, MF_BYPOSITION, y, "mynewitem");
AfxGetMainWnd()->DrawMenuBar();
y++;
}
void CChangeMenu::OnEdit()
{
AfxGetMainWnd()->GetMenu()->ModifyMenu(0, MF_BYPOSITION, 402, "dfd");
AfxGetMainWnd()->DrawMenuBar();
}
DrawMenuBar() 重繪。HMENU 從 CMenu 物件分離,防止物件銷毀時連帶銷毀系統選單控制代碼。0x8000 以上或自訂範圍。GetSubMenu(0) 取得第一個下拉選單,索引從 0 開始。編譯執行後,點選主選單「彈出設定對話框」,在對話框中點擊各按鈕即可觀察主視窗選單動態變化:清空、切換不同選單資源、追加項目、插入子項目、修改文字等效果。
掌握 MFC 動態選單技術,能讓應用程式根據使用者角色、授權或偏好即時調整介面,提升使用體驗。本文範例涵蓋最常見的操作情境,開發者可據此擴充更複雜的選單管理邏輯。