一開始以我是這樣做的,結果是錯誤的:
這段代碼第一次點擊時,會在第6個位置創建MFC菜單,我本以為再次點擊,
menu->GetSubMenu(5)返回的值就不會為空了,但事實是它返回了NULL,所以這樣做動態菜單不得行。
后來我通過百度,搜索出了下面的方法,進行了一點小小的總結。
首先需要在Resource.h文件里定義菜單的宏:
//自定義動態菜單 #define Dyn_Menu_MFC 5000
這里我只定義了一個,后面的菜單項都是直接寫的數字。
為什么要定義這個,是因為,我們無法通過在在資源里的菜單添加命令那樣為動態菜單添加處理函數。所以只能手動的取個標識ID,以便和對應的命令消息處理函數相匹配。
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) ON_WM_CREATE() ON_COMMAND(ID_TEST_MYOPEN, &CMainFrame::OnTestMyopen) ON_COMMAND(Dyn_Menu_MFC, &CMainFrame::OnCommandTest)//處理函數 END_MESSAGE_MAP()
在MainFrame.h里加入:
public: afx_msg void OnTestMyopen(); afx_msg void OnCommandTest();
在MainFrame.cpp加入:
void CMainFrame::OnCommandTest() { CMenu * menu = GetMenu(); CMenu * subMenu = menu->GetSubMenu(0); if (subMenu != NULL) { MessageBox(TEXT("c++學院")); } }
到這里c++學院菜單的處理函數就完成了。
下面這是詳細的動態菜單構建代碼:
CMenu subMenu, menuMain; menuMain.CreateMenu(); subMenu.CreateMenu(); subMenu.AppendMenuW(MF_STRING | MF_ENABLED, Dyn_Menu_MFC, TEXT("c++學院")); // 子項一 menuMain.AppendMenuW(MF_BYPOSITION | MF_POPUP | MF_STRING, (UINT)subMenu.m_hMenu, TEXT("MFC"));//主菜單 subMenu.CheckMenuItem(0, MF_BYPOSITION | MF_CHECKED); //從資源里的已有菜單動態添加到新菜單上 CMenu oldMenu; oldMenu.LoadMenuW(IDR_MAINFRAME); //如果是想獲得當前菜單 //GetMenu() menuMain.AppendMenuW(MF_BYPOSITION | MF_POPUP | MF_STRING, (UINT)oldMenu.GetSubMenu(0)->m_hMenu, TEXT("資源中已存在的菜單")); //創建帶有子菜單的學員分類菜單 CMenu sSubMenu; sSubMenu.CreateMenu(); sSubMenu.AppendMenuW(MF_POPUP, 5555, TEXT("初階學員")); //sSubMenu.AppendMenuW(MF_POPUP, 5556, TEXT("高階學員")); //創建帶有子菜單的高階學員菜單 CMenu ssSubMenu; ssSubMenu.CreateMenu(); ssSubMenu.AppendMenuW(MF_STRING, 5557, TEXT("高階學員_子菜單")); sSubMenu.AppendMenuW(MF_BYPOSITION | MF_POPUP | MF_STRING, (UINT)ssSubMenu.m_hMenu, TEXT("高階學員")); menuMain.GetSubMenu(0)->AppendMenuW(MF_BYPOSITION | MF_POPUP | MF_STRING, (UINT)sSubMenu.m_hMenu, TEXT("學員分類")); SetMenu(&menuMain); menuMain.Detach(); subMenu.Detach(); oldMenu.Detach(); sSubMenu.Detach(); ssSubMenu.Detach();