WEB开发网
开发学院软件开发VC 深入浅出MFC“文档/视图”架构(5)――框架 阅读

深入浅出MFC“文档/视图”架构(5)――框架

 2009-02-11 20:00:28 来源:WEB开发网   
核心提示: 图5.4 MDI Tile的效果MDISetMenu函数的重要意义体现在一个MDI程序可以为不同类型的文档(与文档模板关联)显示不同的菜单,例如下面的这个函数Load一个菜单,深入浅出MFC“文档/视图”架构(5)――框架(5),并将目前主窗口的菜单替换为该菜单:void CMdiView

深入浅出MFC“文档/视图”架构(5)――框架

图5.4 MDI Tile的效果

MDISetMenu函数的重要意义体现在一个MDI程序可以为不同类型的文档(与文档模板关联)显示不同的菜单,例如下面的这个函数Load一个菜单,并将目前主窗口的菜单替换为该菜单:

void CMdiView::OnReplaceMenu()
{
 // Load a new menu resource named IDR_SHORT_MENU
 CMdiDoc* pdoc = GetDocument();
 pdoc->m_DefaultMenu = ::LoadMenu(AfxGetResourceHandle(), MAKEINTRESOURCE(IDR_SHORT_MENU));
 if (pdoc->m_DefaultMenu == NULL)
  return;
 // Get the parent window of this view window. The parent window is
 // a CMDIChildWnd-derived class. We can then obtain the MDI parent
 // frame window using the CMDIChildWnd*. Then, replace the current
 // menu bar with the new loaded menu resource.
 CMDIFrameWnd* frame = ((CMDIChildWnd *) GetParent())->GetMDIFrame();
 frame->MDISetMenu(CMenu::FromHandle(pdoc->m_DefaultMenu), NULL);
 frame->DrawMenuBar();
}
  CMDIFrameWnd类另一个不讲"不足以服众"的函数是OnCreateClient,它是子框架窗口的创造者,其实现如下:

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::OnCreateClient的源代码可以看出,其中真正起核心作用的是对函数CreateClient的调用:
BOOL CMDIFrameWnd::CreateClient(LPCREATESTRUCT lpCreateStruct,
CMenu* pWindowMenu)
{
 ASSERT(m_hWnd != NULL);
 ASSERT(m_hWndMDIClient == NULL);
 DWORD dwStyle = WS_VISIBLE | WS_CHILD | WS_BORDER | WS_CLIPCHILDREN | WS_CLIPSIBLINGS |
MDIS_ALLCHILDSTYLES; // allow children to be created invisible
 DWORD dwExStyle = 0;
 // will be inset by the frame
 if (afxData.bWin4)
 {
  // special styles for 3d effect on Win4
  dwStyle &= ~WS_BORDER;
  dwExStyle = WS_EX_CLIENTEDGE;
 }
 CLIENTCREATESTRUCT ccs;
 ccs.hWindowMenu = pWindowMenu->GetSafeHmenu();
 // set hWindowMenu for MFC V1 backward compatibility
 // for MFC V2, window menu will be set in OnMDIActivate
 ccs.idFirstChild = AFX_IDM_FIRST_MDICHILD;
 if (lpCreateStruct->style & (WS_HSCROLL|WS_VSCROLL))
 {
  // parent MDIFrame's scroll styles move to the MDICLIENT
  dwStyle |= (lpCreateStruct->style & (WS_HSCROLL|WS_VSCROLL));
  // fast way to turn off the scrollbar bits (without a resize)
  ModifyStyle(WS_HSCROLL|WS_VSCROLL, 0, SWP_NOREDRAW|SWP_FRAMECHANGED);
 }
 // Create MDICLIENT control with special IDC
 if ((m_hWndMDIClient = ::CreateWindowEx(dwExStyle, _T("mdiclient"), NULL,
dwStyle, 0, 0, 0, 0, m_hWnd, (HMENU)AFX_IDW_PANE_FIRST,
AfxGetInstanceHandle(), (LPVOID)&ccs)) == NULL)
 {
  TRACE(_T("Warning: CMDIFrameWnd::OnCreateClient: failed to create MDICLIENT.")
_T(" GetLastError returns 0x%8.8Xn"), ::GetLastError());
  return FALSE;
 }
 // Move it to the top of z-order
 ::BringWindowToTop(m_hWndMDIClient);
 return TRUE;
}

上一页  1 2 3 4 5 6  下一页

Tags:深入浅出 MFC 文档

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接