MFC的單文檔中,動態添加頂級菜單

我的一個工具,使用vs2015mfc寫的,單文檔方式。

在打開一個文件的時候,想在當前的菜單中添加我自己的一個頂級菜單,文件關閉的時候,就刪除它。

在插入之前的樣子:

插入之後的樣子:

以下爲實現過程(以下都是在CMainFrame類中添加代碼):

首先定義兩個變量:

	int	m_plugMenuIndex;	// 如果爲-1,則表示沒有插入
	CMenu	m_menuFromPlug;

第一個變量用於記錄這個頂級菜單插入的位置,第二個是插入的菜單內容,在OnCreateClient()初始化:

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
   ...
   m_plugMenuIndex = -1;
   m_menuFromPlug.CreatePopupMenu();
}

當然,放在OnCreate()中初始化也可以。

添加菜單創建函數:

void CMainFrame::UpdateMenuFromPlug()
{
	int menuCount = m_vecMenu.size();
	if (menuCount == 0)
		return;

	CMenu *pmenu = GetMenu();
	unsigned int flag = MF_POPUP | MF_STRING | MF_BYPOSITION;

	// 先創建子菜單,注意,先刪除之前加入的項,因爲這些項在不同狀態下可能會變化
	CString plugMStr = TEXT("高級功能");
	while (m_menuFromPlug.GetMenuItemCount())
	{
		m_menuFromPlug.DeleteMenu(0, MF_BYPOSITION);
	}

	int im;
	flag = MF_ENABLED | MF_STRING;
	for (im = 0; im < menuCount; im++)
	{
		m_menuFromPlug.AppendMenu(flag, IDM_PLUGMENUSTART + im, m_vecMenu[im].strText);
	}

	MENUITEMINFOW menuStru;
	memset(&menuStru, 0, sizeof(menuStru));
	menuStru.cbSize = sizeof(menuStru);
	menuStru.hSubMenu = m_menuFromPlug.GetSafeHmenu();
	menuStru.fMask = MIIM_SUBMENU | MIIM_STRING;
	menuStru.fType = MIIM_STRING;
	menuStru.dwTypeData = (LPWSTR)plugMStr.GetString();
	menuStru.cch = plugMStr.GetLength();

	m_plugMenuIndex = 3;	// 插到第三個位置
	if (!pmenu->InsertMenuItem(m_plugMenuIndex, &menuStru, MF_BYPOSITION))
	{
		// 插入菜單失敗
		m_plugMenuIndex = -1;
	}
}

其中的m_vecMenu是要加入的菜單項列表,定義爲:vector<CString> m_vecMenu; ,在合適的地方插入內容就可以了。

這個函數是先創建這個要插入的頂級菜單,在創建之前,需要刪除之前插入的項,因爲打開不同的文件時,插入的菜單項可能不一樣,所以需要刪除。如果你沒有這些不同,那就沒有必要刪除它,自然,只要創建一次,後面也就不用再去創建它了。

這裏插入的位置設置爲第四項,如果最後在插入到系統菜單時失敗,則置插入的位置爲-1,這樣在文件關閉時就不用刪除它了。

在打開文件的接口中調用該函數 UpdateMenuFromPlug();

這樣就完成了菜單的加載。

在文件關閉時,刪除添加的菜單項,使菜單欄恢復打開文件之前的狀態:

	if (m_plugMenuIndex >= 0)
	{
		CMenu *pmenu = GetMenu();
		pmenu->RemoveMenu(m_plugMenuIndex, MF_BYPOSITION);
		m_plugMenuIndex = -1;
		DrawMenuBar();
	}

注意,刪除之後的 DrawMenuBar() 函數必需調用,否則菜單欄不會刷新,只有當窗口變化的時候它纔會刷新,這樣就影響了界面的顯示效果。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章