• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            C++樂園

            C/C++ 交流

              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
              12 隨筆 :: 18 文章 :: 14 評論 :: 0 Trackbacks
            使用AppWizard創建一個MDI應用程序,我創建的應用程序?叫MDITest,這樣MFC生成了如下的類:
            類名 作用
            CMDITestApp 派生于CWinApp的應用程序類。
            CMainFrame 派生于CMDIFrameWnd的MDI框架窗口類。
            CMDITestDoc 派生于CDocument的文檔類。
            CChildFrame 派生于CMDIChildWnd的MDI子窗口類。
            CMDITestView 派生于CView的文檔顯示類。
            在運行時刻,CMainFrame,?CChildFrame,?CMDITestView的窗口關系如下面的表格示出:
            CMainFrame
            (Menu,?Toolbar?…)
            MDIClient
            ?
            CChildFrame
            CMDITestView
            ???pDocument?=?*CMDITestDoc???(帶有文檔的指針)
            ?
            ?
            ?
            ?
            ?
            [StatusBar]
            其中,最外層的是頂層窗口CMainFrame,里面包含一個MDIClient窗?口。CChildFrame做為子窗口包含于MDIClient中(可以包含多?個),CChildFrame里面則是真實的文檔表示窗口CMDITestView了。
            ?
            我們從這里開始:
            //?CMDITestApp?初始化
            BOOL?CMDITestApp::InitInstance()
            ?
            做為CWinApp的派生類,通常需要重載InitInstance(),?ExitInstance()兩個函數,以完成應?用的初始化和退出。我們現在關心InitInstance中關于文檔模板、窗口處理的部分,而忽略掉一些CommonControl,?OLE初始化部分。
            ?
            整個InitInstance代碼如下:
            BOOL?CMDITestApp::InitInstance()
            {
            ?????InitCommonControls();???????//?這里刪減了大量注釋和錯誤處理
            ?????CWinApp::InitInstance();
            ?????AfxOleInit();
            ?????AfxEnableControlContainer();
            ?????SetRegistryKey(_T("應用程序向導生成的本地應用程序");
            ?????LoadStdProfileSettings(4);??//?加載標準?INI?文件選項(包括?MRU)
            ?
            ?????TRACE("Before?CMultiDocTemplate\n";
            ?????//?注冊應用程序的文檔模板。文檔模?板
            ?????//?將用作文檔、框架窗口和視圖之間的連?接
            ?????CMultiDocTemplate*?pDocTemplate;
            ?????pDocTemplate?=?new?CMultiDocTemplate(IDR_MDITestTYPE,
            ?????????RUNTIME_CLASS(CMDITestDoc),
            ?????????RUNTIME_CLASS(CChildFrame),?//?自定義?MDI?子框架
            ?????????RUNTIME_CLASS(CMDITestView));
            ?????if?(!pDocTemplate)
            ?????????return?FALSE;
            ?????TRACE("Before?AddDocTemplate\n";
            ?????AddDocTemplate(pDocTemplate);
            ?
            ?????//?創建主?MDI?框架窗口
            ?????TRACE("Before?new?CMainFrame\n";
            ?????CMainFrame*?pMainFrame?=?new?CMainFrame;
            ?????TRACE("Before?pMainFrame->LoadFrame\n";
            ?????if?(!pMainFrame?||?!pMainFrame->LoadFrame(IDR_MAINFRAME))
            ?????????return?FALSE;
            ?????m_pMainWnd?=?pMainFrame;
            ?
            ?????TRACE("Before?ParseCommandLine\n";
            ?????CCommandLineInfo?cmdInfo;
            ?????ParseCommandLine(cmdInfo);
            ?
            ?????//?調度在命令行中指定的命令。如?果
            ?????//?用?/RegServer、/Register、/Unregserver?或?/Unregister?啟動應用程序,則返回?FALSE。
            ?????TRACE("Before?ProcessShellCommand\n";
            ?????if?(!ProcessShellCommand(cmdInfo))
            ?????????return?FALSE;
            ?
            ?????TRACE("Before?pMainFrame->ShowWindow\n";
            ?????//?主窗口已初始化,因此顯示它并對其進行更?新
            ?????pMainFrame->ShowWindow(m_nCmdShow);
            ?????TRACE("Before?pMainFrame->UpdateWindow\n";
            ?????pMainFrame->UpdateWindow();
            ?????return?TRUE;
            }
            ?
            為了研究整個創建過程,我在其中添加了一些TRACE來跟蹤創建順序。
            ?
            忽略掉開始的亂七八糟的初始化,從CMultiDocTemplate開始:
            ?????CMultiDocTemplate*?pDocTemplate?=?new?CMultiDocTemplate(IDR_MDITestTYPE,
            ?????????RUNTIME_CLASS(CMDITestDoc),
            ?????????RUNTIME_CLASS(CChildFrame),?//?自定義?MDI?子框架
            ?????????RUNTIME_CLASS(CMDITestView));
            ?????AddDocTemplate(pDocTemplate);
            (作了一點點簡化)
            這里首先創建了一個CMultiDocTemplate?--?new?CMainFrame;
            ?????if?(!pMainFrame?||?!pMainFrame->LoadFrame(IDR_MAINFRAME))
            ?????????return?FALSE;
            ?

            其中,需要研究的是LoadFrame的實現,以及里面都做了些什么。我們稍后研究。
            ?
            處理命令行,在這里第一個空文檔被建立出來:
            ?????CCommandLineInfo?cmdInfo;
            ?????ParseCommandLine(cmdInfo);
            ?
            ?????//?調度在命令行中指定的命令。如果用?/RegServer、/Register、/Unregserver?或?/Unregister?啟動應用程序,則返回?FALSE。
            ?????if?(!ProcessShellCommand(cmdInfo))???????????????//???這里創建出初始空文?檔
            ?????????return?FALSE;
            ?
            我們一會會重點研究ProcessShellCommand。
            ?
            最后,顯示主窗口:
            ?????pMainFrame->ShowWindow(m_nCmdShow);
            ?????pMainFrame->UpdateWindow();
            ?
            至此,WinApp::InitInstance()完成了自己的工作。
            ?
            上面遺留了三個待研究的分支,讓我們現在去研究它們:
            1、??CDocTemplate
            2、??CFrameWnd::LoadFrame
            3、??CWnd::ProcessShellCommand
            ?
            ?
            ?
            研究CDocTemplate
            ?
            我們的例子中是構造了一個CMultiDocTemplate,它是從CDocTemplate派生而來,所以我們主?要研究CDocTemplate。
            CDocTemplate的幾個關鍵屬性列表如下:
            ?????CRuntimeClass*?m_pDocClass;?????????//?class?for?creating?new?documents
            ?????CRuntimeClass*?m_pFrameClass;???????//?class?for?creating?new?frames
            ?????CRuntimeClass*?m_pViewClass;????????//?class?for?creating?new?views
            ?
            其中:
            m_pDocClass 表示文檔類類型,在此例子中就是CMDITestDoc
            m_pFrameClass 表示容納View窗口的框架窗口類類型,此例中為CChildFrame
            m_pViewClass 表示顯示文檔的View視類類型,此例中為CMDITestView
            ?
            我們可以這樣認為,CDocTemplate用于描述Frame-View-Doc的關系。當然它還有一大堆別的屬?性,我們暫時先忽略。
            ?
            一會還會看到CDocTemplate的創建文檔、框架、視的過程,放在ProcessShellCommand中研究。
            ?
            ?
            研究LoadFrame
            ?
            讓我們繼續研究CFrameWnd::LoadFrame是怎么運作的。使用的方法是跟蹤進入。。。
            BOOL?CMDIFrameWnd::LoadFrame(UINT?nIDResource,?DWORD?dwDefaultStyle,
            ?????CWnd*?pParentWnd,?CCreateContext*?pContext)
            {
            ?????//?調用基類?CFrameWnd?的?LoadFrame,?pContext?在創建主窗口時?=?NULL
            ?????//???pParentWnd?=?NULL
            ?????if?(!CFrameWnd::LoadFrame(nIDResource,?dwDefaultStyle,
            ???????pParentWnd,?pContext))
            ?????????return?FALSE;
            ?
            ?????//?save?menu?to?use?when?no?active?MDI?child?window?is?present
            ?????ASSERT(m_hWnd?!=?NULL);
            ?????//?主窗口帶有菜單,所以。。。
            ?????m_hMenuDefault?=?::GetMenu(m_hWnd);
            ?????if?(m_hMenuDefault?==?NULL)
            ?????????TRACE(traceAppMsg,?0,?"Warning:?CMDIFrameWnd?without?a?default?menu.\n";
            ?????return?TRUE;
            }
            注意,我們的MDITest?Application的主窗口CMainFrame是?從CMDIFrameWnd派生的,所以進入到這里,參考代碼中紅色的注釋部分。繼續跟蹤進入CFrameWnd::LoadFrame。
            ?
            BOOL?CFrameWnd::LoadFrame(UINT?nIDResource,?DWORD?dwDefaultStyle,
            ?????CWnd*?pParentWnd,?CCreateContext*?pContext)
            {
            ?????//?only?do?this?once
            ?????ASSERT_VALID_IDR(nIDResource);????//?nIDResource?=?128,?IDR_MAINFRAME
            ?????ASSERT(m_nIDHelp?==?0?||?m_nIDHelp?==?nIDResource);
            ?
            ?????m_nIDHelp?=?nIDResource;????//?ID?for?help?context?(+HID_BASE_RESOURCE)
            ?
            ?????CString?strFullString;
            ?????if?(strFullString.LoadString(nIDResource))??//?=?"MDITest"
            ?????????AfxExtractSubString(m_strTitle,?strFullString,?0);????//?取得第一個子串
            ?
            ?????VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG));
            ?
            ?????//?attempt?to?create?the?window
            ?????//?GetIconWndClass?會調用?virtual?PreCreateWindow?函數,別處也會調用,從而
            ?????//?使得子類的PreCreateWindow?將被調用多次
            ?????LPCTSTR?lpszClass?=?GetIconWndClass(dwDefaultStyle,?nIDResource);
            ?????CString?strTitle?=?m_strTitle;
            ?????//?調用?CFrameWnd::Create()?實際創建出窗?口。
            ?????//?注意:在這里將給?CMainFrame?發送?WM_CREATE?等多個消息。?觸發?CMainFrame?的
            ?????//???OnCreate?處理等。
            ?????if?(!Create(lpszClass,?strTitle,?dwDefaultStyle,?rectDefault,
            ???????pParentWnd,?MAKEINTRESOURCE(nIDResource),?0L,?pContext))
            ?????{
            ?????????return?FALSE;???//?will?self?destruct?on?failure?normally
            ?????}
            ?
            ?????//?save?the?default?menu?handle,?好像?CMDIFrameWnd?也保存了一次?
            ?????ASSERT(m_hWnd?!=?NULL);
            ?????m_hMenuDefault?=?::GetMenu(m_hWnd);
            ?
            ?????//?load?accelerator?resource
            ?????LoadAccelTable(MAKEINTRESOURCE(nIDResource));
            ?
            ?????//?WM_INITIALUPDATE?是?MFC?發明的消息,參見后?面的說明。
            ?????if?(pContext?==?NULL)???//?send?initial?update
            ?????????SendMessageToDescendants(WM_INITIALUPDATE,?0,?0,?TRUE,?TRUE);
            ?
            ?????return?TRUE;
            }
            ?
            以下是從TN024:?MFC-Defined?Messages?And?Resources中抽取的部分說明:
            WM_INITIALUPDATE
            This?message?is?sent?by?the?document?template?to?all?descendants?of?a?frame?window?when?it?is?safe?for?them?to?do?their?initial?update.?It?maps?to?a?call?to?CView::OnInitialUpdate?but?can?be?used?in?other?CWnd-derived?classes?for?other?one-shot?updating.
            wParam Not?used?(0)
            lParam Not?used?(0)
            returns Not?used?(0)

            ?
            歸納一下,LoadFrame中進行了如下事情:
            1、??注冊窗口類(AfxDeferRegisterClass)
            2、??實際創建窗口(Create)
            3、??處理菜單、快捷鍵,發送WM_INITIALUPDATE消息給所有子窗口。實際將?在CView中處理此消息。(例如:在ToolBar上面放一?個FormView,可能就能收到這個消息并處利?)
            ?
            至此,CMainFrame已經成功創建,菜單已經裝載,工具條、狀態行等已經在CMainFrame::OnCreate中創建。讓我們接著研究第一個子窗口是怎么被創建出來的,該過程和CMainFrame::LoadFrame比起來就不那么直接了。
            ?
            ?
            研究CWnd::ProcessShellCommand
            ?
            第一個MDI子窗口是從這里面建立出來的,這實在是缺乏直觀性。不過MFC就是這樣,沒辦法。?
            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;
            ?
            ?????case?CCommandLineInfo::FileOpen:????????????????//?忽?略
            ?????case?CCommandLineInfo::FilePrintTo:????????????//?忽略
            ?????case?CCommandLineInfo::FilePrint:
            ?????case?CCommandLineInfo::FileDDE:
            ?????case?CCommandLineInfo::AppRegister:
            ?????case?CCommandLineInfo::AppUnregister:
            ?????}
            ?????return?bResult;
            }
            進入到ProcessShellCommand,要處理很多種不同命令,我們忽略其它命令,單獨看FileNew部分。
            注意:實際進入到了AfxGetApp()->OnCmdMsg(ID_FILE_NEW,?0,?NULL,?NULL)之中。
            ?
            AfxGetApp()實際返回了CMDITestApp的唯一實例,它從CWinApp?-?CWinThread?-?CCmdTarget?-?CObject?派生而來。我們沒有重載OnCmdMsg,所以進入到CCmdTarget的OnCmdMsg處理中。為了研究,我們刪減了一些代碼。
            BOOL?CCmdTarget::OnCmdMsg(UINT?nID,?int?nCode,?void*?pExtra,
            ?????AFX_CMDHANDLERINFO*?pHandlerInfo)
            {
            ?????//?這里刪減了一些代碼
            ?????//?determine?the?message?number?and?code?(packed?into?nCode)
            ?????const?AFX_MSGMAP*?pMessageMap;
            ?????const?AFX_MSGMAP_ENTRY*?lpEntry;
            ?????UINT?nMsg?=?0;
            ?????//?這里刪減了一些代碼,處理后?nMsg?=?WM_COMMAND
            ?????//?為了簡化,刪減了一些斷言等。以下循環用于查找處理此消息的?入口。
            ?????for?(pMessageMap?=?GetMessageMap();?pMessageMap->pfnGetBaseMap?!=?NULL;
            ???????pMessageMap?=?(*pMessageMap->pfnGetBaseMap)())
            ?????{
            ?????????lpEntry?=?AfxFindMessageEntry(pMessageMap->lpEntries,?nMsg,?nCode,?nID);
            ?????????if?(lpEntry?!=?NULL)
            ?????????{
            ??????????????//?找到了消息處理項入口,分發此消息。
            ??????????????return?_AfxDispatchCmdMsg(this,?nID,?nCode,
            lpEntry->pfn,?pExtra,?lpEntry->nSig,?pHandlerInfo);
            ?????????}
            ?????}
            ?????return?FALSE;???//?未找到則不處理
            }
            最終MFC很愉快地找到了一個入口項,???????CWinApp::OnFileNew(void)???????要處理這個消息。繼續進入到_AfxDispatchCmdMsg中去看看。
            ?
            AFX_STATIC?BOOL?AFXAPI?_AfxDispatchCmdMsg(CCmdTarget*?pTarget,?UINT?nID,?int?nCode,
            ?????AFX_PMSG?pfn,?void*?pExtra,?UINT_PTR?nSig,?AFX_CMDHANDLERINFO*?pHandlerInfo)
            ?????????//?return?TRUE?to?stop?routing
            {
            ?????union?MessageMapFunctions?mmf;
            ?????mmf.pfn?=?pfn;
            ?????BOOL?bResult?=?TRUE;?//?default?is?ok
            ?
            ?????if?(pHandlerInfo?!=?NULL)
            ?????{
            ?????????//?just?fill?in?the?information,?don't?do?it
            ?????????pHandlerInfo->pTarget?=?pTarget;
            ?????????pHandlerInfo->pmf?=?mmf.pfn;
            ?????????return?TRUE;
            ?????}
            ?
            ?????switch?(nSig)
            ?????{
            ?????case?AfxSigCmd_v:
            ?????????//?normal?command?or?control?notification
            ?????????ASSERT(CN_COMMAND?==?0);????????//?CN_COMMAND?same?as?BN_CLICKED
            ?????????ASSERT(pExtra?==?NULL);
            ?????????(pTarget->*mmf.pfnCmd_v_v)();?????????//???實際調用?pTarget?指向?的這個成員函數
            ?????????break;
            ?????//?下面還有大量的多種?AfxSigCmd_xxx,忽略掉它們。
            ?????default:????//?illegal
            ?????????ASSERT(FALSE);?return?0;?break;
            ?????}
            ?????return?bResult;
            }
            ?
            其中?(pTarget->*mmf.pfn_Cmd_v_v)()?對CWinApp::OnFileNew()?產生調?用,pTarget?=?CMDITestApp類實例。調用進入如下:
            ?
            void?CWinApp::OnFileNew()
            {
            ?????if?(m_pDocManager?!=?NULL)
            ?????????m_pDocManager->OnFileNew();
            }
            ?
            進入進入到CDocManager::OnFileNew()
            ?
            void?CDocManager::OnFileNew()
            {
            ?????if?(m_templateList.IsEmpty())
            ??????????//?提示沒有模板并返回
            ?????CDocTemplate*?pTemplate?=?(CDocTemplate*)m_templateList.GetHead();????//?第一個
            ?????if?(m_templateList.GetCount()?>?1)
            ??????????//?彈出一個對話框(很難看的)提示用戶選擇一個文檔模板
            ?
            ?????//?在這個例子里面,pTemplate?就是?CMDITestApp::InitInstance()?里面創建的那個模板
            ?????pTemplate->OpenDocumentFile(NULL);
            }
            ?
            在進入CMultiDocTemplate::OpenDocumentFile之前,我觀察了一下調用堆棧,結果如下:
            >???mfc71d.dll!CDocManager::OnFileNew()??852??C++
            ????mfc71d.dll!CWinApp::OnFileNew()??行?25???C++
            ????mfc71d.dll!_AfxDispatchCmdMsg(CCmdTarget?*?pTarget=0x0042cae8,?unsigned?int?nID=57600,?int?nCode=0,?void?(void)*?pfn=0x0041153c,?void?*?pExtra=0x00000000,?unsigned?int?nSig=53,?AFX_CMDHANDLERINFO?*?pHandlerInfo=0x00000000)??行89???C++
            ????mfc71d.dll!CCmdTarget::OnCmdMsg(unsigned?int?nID=57600,?int?nCode=0,?void?*?pExtra=0x00000000,?AFX_CMDHANDLERINFO?*?pHandlerInfo=0x00000000)??396?+?0x27????C++
            ????mfc71d.dll!CWinApp::ProcessShellCommand(CCommandLineInfo?&?rCmdInfo={...})??行27?+?0x1e?C++
            ????MDITest.exe!CMDITestApp::InitInstance()??行?101?+?0xc????C++
            希望我還沒有迷路:)
            ?
            ?
            CMultiDocTemplate::OpenDocumentFile?又是很多很多代碼,讓我們選擇一些。
            CDocument*?CMultiDocTemplate::OpenDocumentFile(LPCTSTR?lpszPathName,
            ?????BOOL?bMakeVisible)
            {
            ?????//?以下代碼刪減了驗證、斷言部?分
            ?????CDocument*?pDocument?=?CreateNewDocument();??????????????//?創建文檔對象
            ?????CFrameWnd*?pFrame?=?CreateNewFrame(pDocument,?NULL);????//?創建框架窗口
            ?
            ?????if?(lpszPathName?==?NULL)
            ?????{
            ?????????pDocument->OnNewDocument();???????????//?初始化文檔
            ?????}
            ?????else
            ??????????//?打開已有文檔
            ?
            ?????InitialUpdateFrame(pFrame,?pDocument,?bMakeVisible);
            ?????return?pDocument;
            }
            ?
            ?
            看一看CreateNewDocument()
            CDocument*?CDocTemplate::CreateNewDocument()
            {
            ?????//?default?implementation?constructs?one?from?CRuntimeClass
            ?????if?(m_pDocClass?==?NULL)
            ??????????//?錯誤提示啦
            ?????//?CRuntimeClass*?m_pDocClass?->?CreateObject?實例化文檔?類。
            ?????//?在此例子中既是?CMDITestDoc
            ?????CDocument*?pDocument?=?(CDocument*)m_pDocClass->CreateObject();
            ?????AddDocument(pDocument);??????//?添加到模板里的文檔列表,MultiDocTemplate?保存此一文?檔
            ?????return?pDocument;
            }
            ?
            ?
            CMDITestDoc有如下的定義,僅能從CRuntimeClass里面創建的。
            class?CMDITestDoc?:?public?CDocument
            {
            protected:?//?僅從序列化創建
            ?????CMDITestDoc();???????????????//?被保護的構造函數
            ?????DECLARE_DYNCREATE(CMDITestDoc)?????????????//?支持從?CRuntimeClass?信息中創建。
            ?
            ?
            再接著進行CreateNewFrame。
            CFrameWnd*?CDocTemplate::CreateNewFrame(CDocument*?pDoc,?CFrameWnd*?pOther)
            {
            ?????//?create?a?frame?wired?to?the?specified?document
            ?????CCreateContext?context;???????????//?這個?CreateContext?傳遞到?LoadFrame?中
            ?????context.m_pCurrentFrame?=?pOther;?????????//?此例中?=?NULL
            ?????context.m_pCurrentDoc?=?pDoc;??????????????//?=?剛才創建的文檔
            ?????context.m_pNewViewClass?=?m_pViewClass;???//?顯示此文檔的視類的類型
            ?????context.m_pNewDocTemplate?=?this;
            ?
            ?????if?(m_pFrameClass?==?NULL)
            ??????????//?提示錯誤并返回
            ?????//?利用?CRuntimeClass?信息創建框架窗口對象,此例中為?CChildFrame
            ?????CFrameWnd*?pFrame?=?(CFrameWnd*)m_pFrameClass->CreateObject();
            ?
            ?????//?這里,我們又看到了?LoadFrame?,?參考前面的?LoadFrame?吧
            ?????//?在這里面,View?窗口也被產生出來。參考?TRACE?輸?出。
            ?????pFrame->LoadFrame(m_nIDResource,
            ??????????????WS_OVERLAPPEDWINDOW?|?FWS_ADDTOTITLE,???//?default?frame?styles
            ??????????????NULL,?&context);
            ?????return?pFrame;
            }
            ?
            ?
            LoadFrame之后View窗口將被創建出來,接著進入?到CMDITestDoc::OnNewDocument中,現在僅僅是一個空的函數,沒有特定代碼。
            BOOL?CMDITestDoc::OnNewDocument()
            {
            ???TRACE("CMDITestDoc::OnNewDocument()?entry\n";
            ?????if?(!CDocument::OnNewDocument())
            ?????????return?FALSE;
            ?
            ?????//?TODO:?在此添加重新初始化代?碼
            ?????//?(SDI?文檔將重用該文檔)
            ?
            ?????return?TRUE;
            }
            ?
            最后是CDocTemplate::InitialUpdateFrame,這里面主要是激活新建的框架、文檔、視,看得挺頭疼的。
            void?CDocTemplate::InitialUpdateFrame(CFrameWnd*?pFrame,?CDocument*?pDoc,
            ?????BOOL?bMakeVisible)
            {
            ?????//?just?delagate?to?implementation?in?CFrameWnd
            ?????pFrame->InitialUpdateFrame(pDoc,?bMakeVisible);
            }
            ?
            現在,文檔、框架窗口、視窗口全部被創建出來,我們勝利的返回到ProcessShellCommand處。顯示和更新主窗口,完成了WinApp::InitInstance?:
            ?????//?主窗口已初始化,因此顯示它并對其進行更?新
            ?????pMainFrame->ShowWindow(m_nCmdShow);
            ?????pMainFrame->UpdateWindow();
            ?
            ?
            ?
            看一下至此的TRACE輸出,中間的DLL加載被去掉了:
            Before?CMultiDocTemplate
            Before?AddDocTemplate
            Before?new?CMainFrame
            CMainFrame::CMainFrame()
            Before?pMainFrame->LoadFrame
            CMainFrame::PreCreateWindow?entry?????????//?注意:PreCreateWindow?被兩次調用
            CMainFrame::PreCreateWindow?entry
            CMainFrame::OnCreate?entry?before?CMDIFrameWnd::OnCreate
            CMainFrame::OnCreate?before?m_wndToolBar.CreateEx
            CMainFrame::OnCreate?before?m_wndStatusBar.Create
            Before?ParseCommandLine
            Before?ProcessShellCommand
            CMDITestDoc::CMDITestDoc()???????//?文檔對象被創建
            CChildFrame::CChildFrame()???????//?子框架窗口被創建
            CChildFrame::PreCreateWindow?entry?
            CChildFrame::PreCreateWindow?entry
            CChildFrame::PreCreateWindow?entry
            CMDITestView::CMDITestView()?entry???//?子框架窗口的?OnCreate?中創建了?View?窗口
            CMDITestView::PreCreateWindow?entry
            CMDITestDoc::OnNewDocument()?entry
            Before?pMainFrame->ShowWindow
            Before?pMainFrame->UpdateWindow
            ?
            //?退出時的?TRACE
            CMDITestView::~CMDITestView()
            CChildFrame::~CChildFrame()
            CMDITestDoc::~CMDITestDoc()
            CMainFrame::~CMainFrame()
            posted on 2007-03-22 19:34 小不懂^_^ 閱讀(1055) 評論(0)  編輯 收藏 引用 所屬分類: Windows編程
            久久精品成人国产午夜| 久久久久久久久无码精品亚洲日韩| 久久久免费精品re6| 69SEX久久精品国产麻豆| 久久久久综合网久久| 久久久久无码专区亚洲av| 久久久国产亚洲精品| 久久久久人妻精品一区| 中文字幕亚洲综合久久| 伊人久久大香线蕉综合5g| 99久久精品午夜一区二区| 久久91这里精品国产2020| 漂亮人妻被中出中文字幕久久| 久久99国产综合精品免费| 亚洲国产成人久久综合野外| 久久精品无码专区免费青青| 精品久久久久久无码人妻蜜桃| 狠狠精品久久久无码中文字幕| 国产亚州精品女人久久久久久| 婷婷五月深深久久精品| 国产午夜精品久久久久免费视| 久久精品无码一区二区三区日韩 | 日韩久久无码免费毛片软件| 日本欧美久久久久免费播放网| 久久久久国产一区二区| 久久久久久综合一区中文字幕| 精品久久久中文字幕人妻| 青青草原综合久久大伊人导航| 嫩草影院久久99| 久久久久久亚洲AV无码专区| 色老头网站久久网| 日本加勒比久久精品| 久久国产精品无码网站| 91精品国产高清久久久久久国产嫩草| 久久男人Av资源网站无码软件 | 亚洲欧美一区二区三区久久| 国产精品激情综合久久| 久久精品国产亚洲一区二区| 精品一区二区久久| 色综合久久最新中文字幕| 国产2021久久精品|