书上说(P347),当使用者欲打开一份文件的时候(通常是接着【File/open】,【File/New】命令时),然后CDocTemplate会动态创建Document/View/Frame这三个对象。
我的问题是,当编译通过开始运行程序的时候,(这时我们并没有机会调用【File/open】,【File/New】),程序会出现一个界面,这时候CDocument/View/Fream对象又是怎么创建的呢?

解决方案 »

  1.   

    奥秘在于InitInstance函数中如下二句:
    CCommandLineInfo cmdInfo;
    ParseCommandLine(cmdInfo);

    楼主可参考此文http://apps.hi.baidu.com/share/detail/40404977,讲得很详细。
    MFC因为是对api函数的封装,所以很多细节要深挖好几屋才能发现,从使用者的角度而言,具体深入到什么程度,可灵活掌握。有兴趣的话,可以在调试时按F11进入函数内部看看源代码。
      

  2.   


    // App类的InitIntance函数中有这么一句:
    if (!ProcessShellCommand(cmdInfo))
    return FALSE;// 然后你F11进入就可以看到了
    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;
    }