MFC 单文档创建过程

点击ON_FILE_NEW -----------> CWInApp::OnFileNew ({ m_pDocManager->OnFileNew) 

m_pDocManager.OnFileNew {  判断其m_tempList是不是空,然后判断是不是>1 然后用模板CDocTemplate->OpenDocumentFIle(就是单文档,我们单文档OnDocumentFile

创建文件对象,框架对象,视类对象。 CreateFrame创建窗口视图,其中创建窗口对象后调用LoadFrame方法,然后调用父类虚函数Create函数。

单文档在每次NewFile中 框架对象视类文档对象不会创建。只创建一次重复调用。

注意在InitInstance中创建文档模板对象,添加进去。只是添加了类名RTTI没有创建窗口等。


一定要理解对象创建和窗口创建是两个事情,类不等于窗体,窗体只不过是类中成员函数调用CreateWindowEx保存了一个句柄,类中包含着非窗体的其他数据。


在创建模板时候通过一个 IDR_MAINFRAME,//包含多种资源用/n隔开传递进入模板,CDocTemplate.GetDocString获得



在单文档中,最先创建的是文档类。当app类的InitInstance函数中调用ProcessShellCommand函数时,调用了OnFileNew函数(如果你是新建一个单文档程序的话),最终经过一系列调用,在CSingleDocTemplate类的OpenDocumentFile函数中创建了文档类。
在OpenDocumentFile函数中,先创建了文档类,然后创建窗体类,在窗体类创建的尾声,响应了OnCreate函数,你可以在CMainFrame类OnCreate函数中看到,此函数调用了父类的OnCreate函数(代码:CFrameWnd::OnCreate(lpCreateStruct)),也就是在底层的OnCreate函数中调用OnCreateClient函数创建了视图类。
具体流程你可以设置断点调试一下就知道了,在app类的InitInstance函数中单步调试,然后分别在文档、窗体和视图的构造函数中添加断点,一试就知道了



BOOL CWinApp::ProcessShellCommand(CCommandLineInfo& rCmdInfo)
{
BOOL bResult = TRUE;
switch (rCmdInfo.m_nShellCommand)
{
case CCommandLineInfo::FileNew:
if (!AfxGetApp()->OnCmdMsg(ID_FILE_NEW, 0, NULL, NULL))
OnFileNew();
if (m_pMainWnd == NULL)
bResult = FALSE;
break;


// If we've been asked to open a file, call OpenDocumentFile()


case CCommandLineInfo::FileOpen:
if (!OpenDocumentFile(rCmdInfo.m_strFileName))
bResult = FALSE;
break;


// If the user wanted to print, hide our main window and
// fire a message to ourselves to start the printing


case CCommandLineInfo::FilePrintTo:
case CCommandLineInfo::FilePrint:
m_nCmdShow = SW_HIDE;
ASSERT(m_pCmdInfo == NULL);
OpenDocumentFile(rCmdInfo.m_strFileName);
m_pCmdInfo = &rCmdInfo;
m_pMainWnd->SendMessage(WM_COMMAND, ID_FILE_PRINT_DIRECT);
m_pCmdInfo = NULL;
bResult = FALSE;
break;


// If we're doing DDE, hide ourselves


case CCommandLineInfo::FileDDE:
m_pCmdInfo = (CCommandLineInfo*)m_nCmdShow;
m_nCmdShow = SW_HIDE;
break;


// If we've been asked to unregister, unregister and then terminate
case CCommandLineInfo::AppUnregister:
{
UnregisterShellFileTypes();
BOOL bUnregistered = Unregister();


// if you specify /EMBEDDED, we won't make an success/failure box
// this use of /EMBEDDED is not related to OLE


if (!rCmdInfo.m_bRunEmbedded)
{
if (bUnregistered)
AfxMessageBox(AFX_IDP_UNREG_DONE);
else
AfxMessageBox(AFX_IDP_UNREG_FAILURE);
}
bResult = FALSE;    // that's all we do


// If nobody is using it already, we can use it.
// We'll flag that we're unregistering and not save our state
// on the way out. This new object gets deleted by the
// app object destructor.


if (m_pCmdInfo == NULL)
{
m_pCmdInfo = new CCommandLineInfo;
m_pCmdInfo->m_nShellCommand = CCommandLineInfo::AppUnregister;
}
}
break;
}
return bResult;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值