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);
}
这边没有CreateView,所以主Frame框架不会去主动产生View的
CMDIChildFrame > CFrameWnd
BOOL CFrameWnd::OnCreateClient(LPCREATESTRUCT, CCreateContext* pContext)
{
// default create client will create a view if asked for it
if (pContext != NULL && pContext->m_pNewViewClass != NULL)
{
if (CreateView(pContext, AFX_IDW_PANE_FIRST) == NULL)
return FALSE;
}
return TRUE;
}
找到差别了吗?关键CFrameWnd::OnCreateClient 与CMDIFrameWnd::OnCreateClient是不一样的!!!!!!!!
这边则是有这个CreateView,即frame/view/document 三位一体的这个childframe会主动产生view,如果你virtual这个OnCreateClient,并且有splitter的话,那么不要去用CFrameWnd这个基类的OnCreateClient,而是自己去调用创建view的办法
int CFrameWnd::OnCreate(LPCREATESTRUCT lpcs)
{
CCreateContext* pContext = (CCreateContext*)lpcs->lpCreateParams;
return OnCreateHelper(lpcs, pContext);
}
int CFrameWnd::OnCreateHelper(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
if (CWnd::OnCreate(lpcs) == -1)
return -1;
// create special children first
if (!OnCreateClient(lpcs, pContext))
{
TRACE0("Failed to create client pane/view for frame./n");
return -1;
}
// post message for initial message string
PostMessage(WM_SETMESSAGESTRING, AFX_IDS_IDLEMESSAGE);
// make sure the child windows have been properly sized
RecalcLayout();
return 0; // create ok
}
这是这个调用顺序OnCreate > OnCreateHelper > OnCreateClient 接下来分叉
MainFrame : public CMDIFrameWnd 有virtual OnCreate :基类OnCreate以后,去初始化status bar / tool bar等。
CMDIChildWnd 没有virtual OnCreate 所以调用基类CFrameWnd::OnCreateClient
但是Splitter不想这么简单的CreateView,要自定义创建view,所以不要这么搞,所以Virtual OnCreateClient,不要让他去调用CreateView, 而是布局好Splitter各子窗口的位置,以后,自己调用创建函数去产生View
以下是流程:
MainFrame virtual OnCreate -> CMDIFrameWnd::OnCreate
CFrameWnd::OnCreateHelper
CMDIFrameWnd::OnCreateClient no CreateView
若是有CSplitter拆分子窗口的话
CFrameWnd::OnCreate
CFrameWnd::OnCreateHelper
ChildView virtual OnCreateClient -> 布局子窗口splitter以及自己去产生view的代码
若是没有CSplitter的话,普通的ChildFrame
CFrameWnd::OnCreate
CFrameWnd::OnCreateHelper
CFrameWnd::OnCreateClient ->自动产生CreateView
不用virtual任何一个函数