我看了相关文档,CMDIFrameWnd::OnCreate函数在创建MDI子窗口后,会吧窗口的名称增加到菜单的窗口列表中,选择子菜单的代码如下: BOOL CMDIFrameWnd::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext*) { CMenu* pMenu = NULL; if (m_hMenuDefault == NULL) { // default implementation for MFC V1 backward compatibility pMenu = GetMenu(); ASSERT(pMenu != NULL); // This is attempting to guess which sub-menu is the Window menu. // The Windows user interface guidelines say that the right-most // menu on the menu bar should be Help and Window should be one // to the left of that. int iMenu = pMenu->GetMenuItemCount() - 2; // If this assertion fails, your menu bar does not follow the guidelines // so you will have to override this function and call CreateClient // appropriately or use the MFC V2 MDI functionality. ASSERT(iMenu >= 0); pMenu = pMenu->GetSubMenu(iMenu); ASSERT(pMenu != NULL); } return CreateClient(lpcs, pMenu); }这说明CMDIFrameWnd其实是在选择从右往左第2个菜单,并把窗口名称附加其上。如果仅仅是这样,那么,我更换菜单资源后,应该能够看到菜单列表。 现在看不到,说明还有其他判断标准,我想问的是这个判断标准时什么,怎样才能让CMDIFrameWnd把列表动态添加到我的菜单资源。
你忽略了一个问题 pMenu = GetMenu(); 这里GetMenu会得到你新建的菜单么?
你自己照着MFC的方法自己做一个
不是可以自己新建自己想要的菜单模板资源,然后再 BOOL CMyApp::InitInstance()这个函数把菜单资源加载不就行了吗?BOOL CMyApp::InitInstance() { CMultiDocTemplate* pDocTemplate; pDocTemplate = new CMultiDocTemplate( IDR_MUITYPE, RUNTIME_CLASS(CMyDoc), RUNTIME_CLASS(CChildFrame), RUNTIME_CLASS(CMyView)); AddDocTemplate(pDocTemplate); // create main MDI Frame window CMainFrame* pMainFrame = new CMainFrame; if (!pMainFrame->LoadFrame(IDR_MENU2)) return FALSE; m_pMainWnd = pMainFrame; // Parse command line for standard shell commands, DDE, file open CCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo); if(!ProcessShellCommand(cmdInfo)) return FALSE; // The main window has been initialized, so show and update it. m_pMainWnd->ShowWindow(SW_SHOW); m_pMainWnd->UpdateData(); return TRUE; }
问题已经解决了,自己祝贺一下自己。问题的原因,是自己创建的菜单资源中没有任何一个子菜单被mfc框架认为是window子菜单,因此也就没有响应修改子菜单的内容。 mfc的判断标准其实很简单,引用MSDN的原文如下: The default implementation looks for a pop-up menu containing standard Window menu commands such as ID_WINDOW_NEW and ID_WINDOW_TILE_HORZ.Override this member function if you have a Window menu that does not use the standard menu command IDs. 所以,只需要覆盖函数CMDIFrameWnd::GetWindowMenuPopup就可以解决问题,这样,就可以利用mfc框架已有的机制实现窗口列表的功能。
随便建了一个mdi的工程,那个窗口里面可以显示所有已经打开的窗口名称啊
新建MDI程序后,发现MDI窗口列表可以正常显示。
然后更换menu资源后,发现窗口列表就消失了。
有没有高手知道如何通过代码实现相应的功能,但要使用我自己的菜单资源。
请说明思路即可。
看不到相关代码并不代表没有代码
只是MFC封装了
你自己菜单相关功能当然要你自己实现
每创建一个窗口就动态为window菜单添加一个菜单项即可
BOOL CMDIFrameWnd::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext*)
{
CMenu* pMenu = NULL;
if (m_hMenuDefault == NULL)
{
// default implementation for MFC V1 backward compatibility
pMenu = GetMenu();
ASSERT(pMenu != NULL);
// This is attempting to guess which sub-menu is the Window menu.
// The Windows user interface guidelines say that the right-most
// menu on the menu bar should be Help and Window should be one
// to the left of that.
int iMenu = pMenu->GetMenuItemCount() - 2; // If this assertion fails, your menu bar does not follow the guidelines
// so you will have to override this function and call CreateClient
// appropriately or use the MFC V2 MDI functionality.
ASSERT(iMenu >= 0);
pMenu = pMenu->GetSubMenu(iMenu);
ASSERT(pMenu != NULL);
} return CreateClient(lpcs, pMenu);
}这说明CMDIFrameWnd其实是在选择从右往左第2个菜单,并把窗口名称附加其上。如果仅仅是这样,那么,我更换菜单资源后,应该能够看到菜单列表。
现在看不到,说明还有其他判断标准,我想问的是这个判断标准时什么,怎样才能让CMDIFrameWnd把列表动态添加到我的菜单资源。
pMenu = GetMenu();
这里GetMenu会得到你新建的菜单么?
BOOL CMyApp::InitInstance()这个函数把菜单资源加载不就行了吗?BOOL CMyApp::InitInstance()
{
CMultiDocTemplate* pDocTemplate;
pDocTemplate = new CMultiDocTemplate(
IDR_MUITYPE,
RUNTIME_CLASS(CMyDoc),
RUNTIME_CLASS(CChildFrame),
RUNTIME_CLASS(CMyView));
AddDocTemplate(pDocTemplate); // create main MDI Frame window
CMainFrame* pMainFrame = new CMainFrame;
if (!pMainFrame->LoadFrame(IDR_MENU2))
return FALSE;
m_pMainWnd = pMainFrame; // Parse command line for standard shell commands, DDE, file open
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
if(!ProcessShellCommand(cmdInfo))
return FALSE; // The main window has been initialized, so show and update it.
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateData();
return TRUE;
}
请看一下下面的链接。
http://www.programbbs.com/bbs/view20-29072-1.htm
这个GetMenu的确是得到了没有文档时的菜单的指针。
我有两个问题:
1)有文档存在时的主框架的菜单的指针如何能够获得,合适获得比较合适。
2)MFC框架在什么时机把子菜单的名称添加到了window菜单
盼望高手知道一二,谢谢大家。
问题已经解决了,自己祝贺一下自己。问题的原因,是自己创建的菜单资源中没有任何一个子菜单被mfc框架认为是window子菜单,因此也就没有响应修改子菜单的内容。
mfc的判断标准其实很简单,引用MSDN的原文如下:
The default implementation looks for a pop-up menu containing standard Window menu commands such as ID_WINDOW_NEW and ID_WINDOW_TILE_HORZ.Override this member function if you have a Window menu that does not use the standard menu command IDs.
所以,只需要覆盖函数CMDIFrameWnd::GetWindowMenuPopup就可以解决问题,这样,就可以利用mfc框架已有的机制实现窗口列表的功能。