最近迁移到VS2008下工作,有一个新项目也在这个下面开发。使用了VS2008 Feature Pack下带的MFC9.0的新界面。
项目是MFC MDI Application,问题发现,使用老的方式给MRU添加菜单项,发现不能工作,
后来查阅资料后,发现CMFCMenuBar有SaveLoad菜单项Staus动作,所以必须清理注册表。
但是,清理注册表后,还是没法将MRU加入。我们原本的做法是将最近使用的文件,最近打开的项目存储于Registry中,应用程序里打开文件时来维护和更新这两个列表。
然后修改菜单项,给‘最近使用的文件’,‘最近使用的工程’下插入菜单项,此方法在VS2005工作正常。
但是VS2008下,即使是插入了也没有效果。
后来多方查阅资料,找到一种方法。
在CMDIFrameWndEx中有个Virtual方法,此方法在弹出菜单Show时调用。
BOOL OnShowPopupMenu( CMFCPopupMenu* pMenu );
决定试试看这个方法,能不能起作用。
于是重载这个方法,给CMainFrame的头文件添加函数声明,CPP中实现此函数。
具体代码如下:
BOOL CMainFrame::OnShowPopupMenu( CMFCPopupMenu* pMenu )
{
BOOL bSucceed = CMDIFrameWndEx::OnShowPopupMenu( pMenu );
CMyAPP* pApp = (CMyAPP*)::AfxGetApp();
if(NULL == pApp)
return FALSE;
C_MyMRULog* pMyLog = pApp->GetMainUILog();
if(NULL == pMyLog )
return FALSE;
if (pMenu != NULL &&
pMenu->GetMenuBar ()->CommandToIndex (ID_FILE_MRU_PROJECT_BASE) >= 0)
{
pMenu->RemoveAllItems ();
int nRecentProjectCount = pMyLog->GetLogProjectCount();
CString strProjectName = _T("");
CMenu menuMRU;
menuMRU.LoadMenu(IDR_MENU_MRU_PROJECT);
menuMRU.RemoveMenu(0, MF_BYPOSITION);
if(nRecentProjectCount > 0)
{
BOOL bSuccess = FALSE;
for(int nMenuItemIndex = 0; nMenuItemIndex < nRecentProjectCount; nMenuItemIndex++)
{
strProjectName = pMyLog->GetLogProjectAt(nMenuItemIndex);
bSuccess = menuMRU.InsertMenu(nMenuItemIndex,MF_STRING | MF_BYPOSITION, ID_FILE_MRU_PROJECT_BASE + nMenuItemIndex,strProjectName);
}
}
else
{
//Set first item's text to prompting
CString strPrompt = _T("Project used recently");
menuMRU.InsertMenu(0, MF_STRING | MF_BYPOSITION, ID_FILE_MRU_PROJECT_BASE ,strPrompt);
menuMRU.EnableMenuItem(0, MF_GRAYED | MF_BYPOSITION);
}
pMenu->GetMenuBar ()->ImportFromMenu (menuMRU.GetSafeHmenu(), TRUE);
}
else if (pMenu != NULL &&
pMenu->GetMenuBar ()->CommandToIndex (ID_FILE_MRU_FILE_BASE) >= 0)
{
pMenu->RemoveAllItems ();
int nRecentProjectCount = pMyLog->GetLogFileCount();
CString strFileName = _T("");
CMenu menuMRU;
menuMRU.LoadMenu(IDR_MENU_MRU_PROJECT);
menuMRU.RemoveMenu(0, MF_BYPOSITION);
if(nRecentProjectCount > 0)
{
BOOL bSuccess = FALSE;
for(int nMenuItemIndex = 0; nMenuItemIndex < nRecentProjectCount; nMenuItemIndex++)
{
strFileName = pMyLog->GetLogFileAt(nMenuItemIndex);
bSuccess = menuMRU.InsertMenu(nMenuItemIndex,MF_STRING | MF_BYPOSITION, ID_FILE_MRU_FILE_BASE + nMenuItemIndex,strFileName );
}
}
else
{
//Set first item's text to prompting
CString strPrompt = _T("File used recently");
menuMRU.InsertMenu(0, MF_STRING | MF_BYPOSITION, ID_FILE_MRU_FILE_BASE ,strPrompt);
menuMRU.EnableMenuItem(0, MF_GRAYED | MF_BYPOSITION);
}
pMenu->GetMenuBar ()->ImportFromMenu (menuMRU.GetSafeHmenu(), TRUE);
}
return bSucceed;
}
以上C_MyMRULog 类是一个维护MRU的Class,里面有个List存放最近打开的项目,以及最近打开的文件。
同时还要在开启文件,开启项目后,维护这个List。具体就不贴出来了。