青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

溫故而知新,學(xué)習(xí)MFC框架如何創(chuàng)建的過程收藏

 

下面我們跟蹤一個(gè)MFC MDI的應(yīng)用程序,來溫習(xí)或?qū)W習(xí)一下。

使用AppWizard創(chuàng)建一個(gè)MDI應(yīng)用程序,我創(chuàng)建的應(yīng)用程序叫MDITest,這樣MFC生成了如下的類:

類名

作用

CMDITestApp

派生于CWinApp的應(yīng)用程序類。

CMainFrame

派生于CMDIFrameWnd的MDI框架窗口類。

CMDITestDoc

派生于CDocument的文檔類。

CChildFrame

派生于CMDIChildWnd的MDI子窗口類。

CMDITestView

派生于CView的文檔顯示類。

 

在運(yùn)行時(shí)刻,CMainFrame, CChildFrame, CMDITestView的窗口關(guān)系如下面的表格示出:

CMainFrame

(Menu, Toolbar …)

MDIClient

 

CChildFrame

CMDITestView

   pDocument = *CMDITestDoc   (帶有文檔的指針)

 

 

 

 

 

[StatusBar]

其中,最外層的是頂層窗口CMainFrame,里面包含一個(gè)MDIClient窗口。CChildFrame做為子窗口包含于MDIClient中(可以包含多個(gè)),CChildFrame里面則是真實(shí)的文檔表示窗口CMDITestView了。

 

我們從這里開始:

// CMDITestApp 初始化

BOOL CMDITestApp::InitInstance()

 

做為CWinApp的派生類,通常需要重載InitInstance(), ExitInstance()兩個(gè)函數(shù),以完成應(yīng)用的初始化和退出。我們現(xiàn)在關(guān)心InitInstance中關(guān)于文檔模板、窗口處理的部分,而忽略掉一些CommonControl, OLE初始化部分。

 

整個(gè)InitInstance代碼如下:

BOOL CMDITestApp::InitInstance()

{

     InitCommonControls();       // 這里刪減了大量注釋和錯(cuò)誤處理

     CWinApp::InitInstance();

     AfxOleInit();

     AfxEnableControlContainer();

     SetRegistryKey(_T("應(yīng)用程序向?qū)傻谋镜貞?yīng)用程序"));

     LoadStdProfileSettings(4);  // 加載標(biāo)準(zhǔn) INI 文件選項(xiàng)(包括 MRU)

 

     TRACE("Before CMultiDocTemplate\n");

     // 注冊(cè)應(yīng)用程序的文檔模板。文檔模板

     // 將用作文檔、框架窗口和視圖之間的連接

     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);

 

     // 創(chuàng)建主 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);

 

     // 調(diào)度在命令行中指定的命令。如果

     // 用 /RegServer、/Register、/Unregserver 或 /Unregister 啟動(dòng)應(yīng)用程序,則返回 FALSE。

     TRACE("Before ProcessShellCommand\n");

     if (!ProcessShellCommand(cmdInfo))

         return FALSE;

 

     TRACE("Before pMainFrame->ShowWindow\n");

     // 主窗口已初始化,因此顯示它并對(duì)其進(jìn)行更新

     pMainFrame->ShowWindow(m_nCmdShow);

     TRACE("Before pMainFrame->UpdateWindow\n");

     pMainFrame->UpdateWindow();

     return TRUE;

}

 

為了研究整個(gè)創(chuàng)建過程,我在其中添加了一些TRACE來跟蹤創(chuàng)建順序。

 

忽略掉開始的亂七八糟的初始化,從CMultiDocTemplate開始:

     CMultiDocTemplate* pDocTemplate = new CMultiDocTemplate(IDR_MDITestTYPE,

         RUNTIME_CLASS(CMDITestDoc),

         RUNTIME_CLASS(CChildFrame), // 自定義 MDI 子框架

         RUNTIME_CLASS(CMDITestView));

     AddDocTemplate(pDocTemplate);

(作了一點(diǎn)點(diǎn)簡化)

這里首先創(chuàng)建了一個(gè)CMultiDocTemplate —— 文檔模板,文檔模板包括的三個(gè)運(yùn)行時(shí)刻類信息:Document – CMDITestDoc, FrameWnd – CChildFrame, View – CMDITestView。

然后通過AddDocTemplate函數(shù)將新創(chuàng)建的文檔模板添加到模板管理器之中(我們以后再研究模板管理器)。

 

然后創(chuàng)建主框架窗口CMainFrame:

     CMainFrame* pMainFrame = new CMainFrame;

     if (!pMainFrame || !pMainFrame->LoadFrame(IDR_MAINFRAME))

         return FALSE;

 

其中,需要研究的是LoadFrame的實(shí)現(xiàn),以及里面都做了些什么。我們稍后研究。

 

處理命令行,在這里第一個(gè)空文檔被建立出來:

     CCommandLineInfo cmdInfo;

     ParseCommandLine(cmdInfo);

 

     // 調(diào)度在命令行中指定的命令。如果用 /RegServer、/Register、/Unregserver 或 /Unregister 啟動(dòng)應(yīng)用程序,則返回 FALSE。

     if (!ProcessShellCommand(cmdInfo))               // ß 這里創(chuàng)建出初始空文檔

         return FALSE;

 

我們一會(huì)會(huì)重點(diǎn)研究ProcessShellCommand。

 

最后,顯示主窗口:

     pMainFrame->ShowWindow(m_nCmdShow);

     pMainFrame->UpdateWindow();

 

至此,WinApp::InitInstance()完成了自己的工作。

 

上面遺留了三個(gè)待研究的分支,讓我們現(xiàn)在去研究它們:

1、  CDocTemplate

2、  CFrameWnd::LoadFrame

3、  CWnd::ProcessShellCommand

 

 

 

研究CDocTemplate

 

我們的例子中是構(gòu)造了一個(gè)CMultiDocTemplate,它是從CDocTemplate派生而來,所以我們主要研究CDocTemplate。

CDocTemplate的幾個(gè)關(guān)鍵屬性列表如下:

     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

 

我們可以這樣認(rèn)為,CDocTemplate用于描述Frame-View-Doc的關(guān)系。當(dāng)然它還有一大堆別的屬性,我們暫時(shí)先忽略。

 

一會(huì)還會(huì)看到CDocTemplate的創(chuàng)建文檔、框架、視的過程,放在ProcessShellCommand中研究。

 

 

研究LoadFrame

 

讓我們繼續(xù)研究CFrameWnd::LoadFrame是怎么運(yùn)作的。使用的方法是跟蹤進(jìn)入。。。

BOOL CMDIFrameWnd::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle,

     CWnd* pParentWnd, CCreateContext* pContext)

{

     // 調(diào)用基類 CFrameWnd 的 LoadFrame, pContext 在創(chuàng)建主窗口時(shí) = 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派生的,所以進(jìn)入到這里,參考代碼中紅色的注釋部分。繼續(xù)跟蹤進(jìn)入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);    // 取得第一個(gè)子串

 

     VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG));

 

     // attempt to create the window

     // GetIconWndClass 會(huì)調(diào)用 virtual PreCreateWindow 函數(shù),別處也會(huì)調(diào)用,從而

     // 使得子類的PreCreateWindow 將被調(diào)用多次

     LPCTSTR lpszClass = GetIconWndClass(dwDefaultStyle, nIDResource);

     CString strTitle = m_strTitle;

     // 調(diào)用 CFrameWnd::Create() 實(shí)際創(chuàng)建出窗口。

     // 注意:在這里將給 CMainFrame 發(fā)送 WM_CREATE 等多個(gè)消息。觸發(fā) 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 發(fā)明的消息,參見后面的說明。

     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中進(jìn)行了如下事情:

1、  注冊(cè)窗口類(AfxDeferRegisterClass)

2、  實(shí)際創(chuàng)建窗口(Create)

3、  處理菜單、快捷鍵,發(fā)送WM_INITIALUPDATE消息給所有子窗口。實(shí)際將在CView中處理此消息。(例如:在ToolBar上面放一個(gè)FormView,可能就能收到這個(gè)消息并處利?)

 

至此,CMainFrame已經(jīng)成功創(chuàng)建,菜單已經(jīng)裝載,工具條、狀態(tài)行等已經(jīng)在CMainFrame::OnCreate中創(chuàng)建。讓我們接著研究第一個(gè)子窗口是怎么被創(chuàng)建出來的,該過程和CMainFrame::LoadFrame比起來就不那么直接了。

 

 

研究CWnd::ProcessShellCommand

 

第一個(gè)MDI子窗口是從這里面建立出來的,這實(shí)在是缺乏直觀性。不過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))      // 關(guān)鍵是這里

              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;

}

進(jìn)入到ProcessShellCommand,要處理很多種不同命令,我們忽略其它命令,單獨(dú)看FileNew部分。

注意:實(shí)際進(jìn)入到了AfxGetApp()->OnCmdMsg(ID_FILE_NEW, 0, NULL, NULL)之中。

 

AfxGetApp()實(shí)際返回了CMDITestApp的唯一實(shí)例,它從CWinApp – CWinThread – CCmdTarget – CObject 派生而來。我們沒有重載OnCmdMsg,所以進(jìn)入到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

     // 為了簡化,刪減了一些斷言等。以下循環(huán)用于查找處理此消息的入口。

     for (pMessageMap = GetMessageMap(); pMessageMap->pfnGetBaseMap != NULL;

       pMessageMap = (*pMessageMap->pfnGetBaseMap)())

     {

         lpEntry = AfxFindMessageEntry(pMessageMap->lpEntries, nMsg, nCode, nID);

         if (lpEntry != NULL)

         {

              // 找到了消息處理項(xiàng)入口,分發(fā)此消息。

              return _AfxDispatchCmdMsg(this, nID, nCode,

                   lpEntry->pfn, pExtra, lpEntry->nSig, pHandlerInfo);

         }

     }

     return FALSE;   // 未找到則不處理

}

最終MFC很愉快地找到了一個(gè)入口項(xiàng),       CWinApp::OnFileNew(void)       要處理這個(gè)消息。繼續(xù)進(jìn)入到_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)();         // ß 實(shí)際調(diào)用 pTarget 指向的這個(gè)成員函數(shù)

         break;

     // 下面還有大量的多種 AfxSigCmd_xxx,忽略掉它們。

     default:    // illegal

         ASSERT(FALSE); return 0; break;

     }

     return bResult;

}

 

其中 (pTarget->*mmf.pfn_Cmd_v_v)() 對(duì)CWinApp::OnFileNew() 產(chǎn)生調(diào)用,pTarget = CMDITestApp類實(shí)例。調(diào)用進(jìn)入如下:

 

void CWinApp::OnFileNew()

{

     if (m_pDocManager != NULL)

         m_pDocManager->OnFileNew();

}

 

進(jìn)入進(jìn)入到CDocManager::OnFileNew()

 

void CDocManager::OnFileNew()

{

     if (m_templateList.IsEmpty())

          // 提示沒有模板并返回

     CDocTemplate* pTemplate = (CDocTemplate*)m_templateList.GetHead();    // 第一個(gè)

     if (m_templateList.GetCount() > 1)

          // 彈出一個(gè)對(duì)話框(很難看的)提示用戶選擇一個(gè)文檔模板

 

     // 在這個(gè)例子里面,pTemplate 就是 CMDITestApp::InitInstance() 里面創(chuàng)建的那個(gè)模板

     pTemplate->OpenDocumentFile(NULL);

}

 

在進(jìn)入CMultiDocTemplate::OpenDocumentFile之前,我觀察了一下調(diào)用堆棧,結(jié)果如下:

>   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)

{

     // 以下代碼刪減了驗(yàn)證、斷言部分

     CDocument* pDocument = CreateNewDocument();              // 創(chuàng)建文檔對(duì)象

     CFrameWnd* pFrame = CreateNewFrame(pDocument, NULL);    // 創(chuàng)建框架窗口

 

     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)

          // 錯(cuò)誤提示啦

     // CRuntimeClass* m_pDocClass -> CreateObject 實(shí)例化文檔類。

     // 在此例子中既是 CMDITestDoc

     CDocument* pDocument = (CDocument*)m_pDocClass->CreateObject();

     AddDocument(pDocument);      // 添加到模板里的文檔列表,MultiDocTemplate 保存此一文檔

     return pDocument;

}

 

 

CMDITestDoc有如下的定義,僅能從CRuntimeClass里面創(chuàng)建的。

class CMDITestDoc : public CDocument

{

protected: // 僅從序列化創(chuàng)建

     CMDITestDoc();               // 被保護(hù)的構(gòu)造函數(shù)

     DECLARE_DYNCREATE(CMDITestDoc)             // 支持從 CRuntimeClass 信息中創(chuàng)建。

 

 

再接著進(jìn)行CreateNewFrame。

CFrameWnd* CDocTemplate::CreateNewFrame(CDocument* pDoc, CFrameWnd* pOther)

{

     // create a frame wired to the specified document

     CCreateContext context;           // 這個(gè) CreateContext 傳遞到 LoadFrame 中

     context.m_pCurrentFrame = pOther;         // 此例中 = NULL

     context.m_pCurrentDoc = pDoc;              // = 剛才創(chuàng)建的文檔

     context.m_pNewViewClass = m_pViewClass;   // 顯示此文檔的視類的類型

     context.m_pNewDocTemplate = this;

 

     if (m_pFrameClass == NULL)

          // 提示錯(cuò)誤并返回

     // 利用 CRuntimeClass 信息創(chuàng)建框架窗口對(duì)象,此例中為 CChildFrame

     CFrameWnd* pFrame = (CFrameWnd*)m_pFrameClass->CreateObject();

 

     // 這里,我們又看到了 LoadFrame , 參考前面的 LoadFrame 吧

     // 在這里面,View 窗口也被產(chǎn)生出來。參考 TRACE 輸出。

     pFrame->LoadFrame(m_nIDResource,

              WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE,   // default frame styles

              NULL, &context);

     return pFrame;

}

 

 

LoadFrame之后View窗口將被創(chuàng)建出來,接著進(jìn)入到CMDITestDoc::OnNewDocument中,現(xiàn)在僅僅是一個(gè)空的函數(shù),沒有特定代碼。

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);

}

 

現(xiàn)在,文檔、框架窗口、視窗口全部被創(chuàng)建出來,我們勝利的返回到ProcessShellCommand處。顯示和更新主窗口,完成了WinApp::InitInstance :

     // 主窗口已初始化,因此顯示它并對(duì)其進(jìn)行更新

     pMainFrame->ShowWindow(m_nCmdShow);

     pMainFrame->UpdateWindow();

 

 

 

看一下至此的TRACE輸出,中間的DLL加載被去掉了:

Before CMultiDocTemplate

Before AddDocTemplate

Before new CMainFrame

CMainFrame::CMainFrame()

Before pMainFrame->LoadFrame

CMainFrame::PreCreateWindow entry         // 注意:PreCreateWindow 被兩次調(diào)用

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()       // 文檔對(duì)象被創(chuàng)建

CChildFrame::CChildFrame()       // 子框架窗口被創(chuàng)建

CChildFrame::PreCreateWindow entry

CChildFrame::PreCreateWindow entry

CChildFrame::PreCreateWindow entry

CMDITestView::CMDITestView() entry   // 子框架窗口的 OnCreate 中創(chuàng)建了 View 窗口

CMDITestView::PreCreateWindow entry

CMDITestDoc::OnNewDocument() entry

Before pMainFrame->ShowWindow

Before pMainFrame->UpdateWindow

 

// 退出時(shí)的 TRACE

CMDITestView::~CMDITestView()

CChildFrame::~CChildFrame()

CMDITestDoc::~CMDITestDoc()

CMainFrame::~CMainFrame()

posted on 2009-03-29 10:25 弱水一瓢 閱讀(483) 評(píng)論(1)  編輯 收藏 引用

評(píng)論

# re: 溫故而知新,學(xué)習(xí)MFC框架如何創(chuàng)建的過程收藏 2009-03-29 21:37 Sunshine Alike

字好大~ T_T  回復(fù)  更多評(píng)論   


只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


<2009年3月>
22232425262728
1234567
891011121314
15161718192021
22232425262728
2930311234

導(dǎo)航

統(tǒng)計(jì)

文章分類

最新評(píng)論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美影院成年免费版| 欧美午夜精彩| 亚洲福利视频一区二区| 在线欧美三区| 欧美国产精品va在线观看| 亚洲伦理精品| 欧美一级网站| 影音先锋在线一区| 欧美人成在线视频| 亚洲综合色网站| 久久视频一区二区| 亚洲美女啪啪| 国产免费观看久久| 免费成人激情视频| 亚洲一区二区高清视频| 美女成人午夜| 亚洲综合精品四区| 精品成人在线| 欧美日韩一二区| 久久精品国产77777蜜臀| 亚洲日本精品国产第一区| 久久国产66| 日韩一级黄色大片| 国产精品资源| 欧美成人亚洲成人日韩成人| 亚洲一区二区三区视频播放| 欧美成人综合| 午夜精品久久久久久99热| 亚洲国内在线| 国产亚洲精品久久久| 欧美人在线观看| 久久嫩草精品久久久精品一| 中文精品视频| 91久久嫩草影院一区二区| 欧美亚洲专区| 正在播放亚洲一区| 在线精品国产欧美| 国产精品婷婷| 欧美理论在线播放| 可以看av的网站久久看| 亚洲影院在线| 亚洲精品乱码视频| 欧美黄在线观看| 久久久999国产| 亚洲欧美久久久久一区二区三区| 亚洲日本aⅴ片在线观看香蕉| 国产区亚洲区欧美区| 欧美日韩综合另类| 欧美了一区在线观看| 欧美va天堂| 免费成人黄色| 免费看的黄色欧美网站| 久久国产精品毛片| 亚洲欧美在线网| 中日韩午夜理伦电影免费| 亚洲精品日韩一| 亚洲黄页视频免费观看| 欧美激情麻豆| 亚洲电影免费观看高清| 欧美v日韩v国产v| 欧美1区视频| 老司机aⅴ在线精品导航| 久久精品亚洲一区二区三区浴池| 亚洲欧美亚洲| 午夜激情综合网| 亚洲欧美资源在线| 午夜精品久久久久久久99热浪潮 | 亚洲欧洲另类国产综合| 狠狠色狠狠色综合日日五| 国产一区二区三区黄视频| 国产亚洲毛片| 精品av久久707| 国产一区二区三区最好精华液| 国产日韩欧美在线看| 国产毛片精品视频| 国内精品久久久久国产盗摄免费观看完整版| 国产精品欧美日韩一区二区| 国产精品一二三四区| 国产欧美精品xxxx另类| 国产在线观看一区| 在线观看欧美亚洲| 亚洲精品乱码久久久久久日本蜜臀 | 韩国欧美一区| 在线观看欧美日韩国产| 亚洲国产精品久久久久婷婷老年 | 亚洲在线视频免费观看| 亚洲欧美国产va在线影院| 亚洲欧美久久久| 欧美专区日韩专区| 久久在线免费视频| 欧美日韩国产一区二区三区| 欧美性猛交一区二区三区精品| 国产乱码精品| 在线看片一区| 一区二区三区国产精华| 午夜精品久久久久久99热软件| 久久久久久久久一区二区| 欧美激情欧美激情在线五月| 日韩亚洲欧美中文三级| 欧美一区二区成人6969| 免费欧美日韩国产三级电影| 欧美日韩免费观看中文| 国产欧美综合在线| 亚洲国产一区在线| 亚洲欧美欧美一区二区三区| 久久综合狠狠综合久久激情| 亚洲精品婷婷| 久久精精品视频| 欧美精品一区在线观看| 国产视频一区三区| 9久re热视频在线精品| 午夜视频在线观看一区| 欧美成人免费观看| 亚洲影院免费| 欧美二区在线| 国产亚洲一区二区三区在线观看| 亚洲精品一区二区三| 欧美在线日韩精品| 亚洲精品一级| 久久免费视频这里只有精品| 国产精品高潮呻吟久久av黑人| 亚洲国产精品国自产拍av秋霞| 羞羞漫画18久久大片| 亚洲激情在线观看视频免费| 欧美一区二区三区久久精品| 欧美精品亚洲| 亚洲福利一区| 久久免费高清视频| 亚洲香蕉伊综合在人在线视看| 男女av一区三区二区色多| 国产欧美日韩另类一区| 一本久道综合久久精品| 美女视频黄 久久| 午夜精品视频一区| 国产精品成人国产乱一区| 亚洲精品久久7777| 免费h精品视频在线播放| 亚洲欧美日韩系列| 欧美网站大全在线观看| 亚洲精品国久久99热| 久久人人爽人人| 亚洲欧美综合| 国产精品免费网站| 亚洲天堂视频在线观看| 亚洲日本中文字幕区| 欧美丰满高潮xxxx喷水动漫| **欧美日韩vr在线| 久久欧美中文字幕| 欧美一区二区在线观看| 国产精品一二三四| 性久久久久久| 亚洲一区图片| 国产精品美女主播| 亚洲欧洲av一区二区| 9色porny自拍视频一区二区| 欧美精品免费观看二区| 日韩五码在线| 亚洲精品中文字幕女同| 欧美精品v日韩精品v国产精品| 亚洲欧洲精品成人久久奇米网| 欧美国产日韩在线| 麻豆精品精华液| 亚洲激情视频在线播放| 亚洲高清在线视频| 欧美伦理在线观看| 亚洲视频一二三| av成人激情| 国产精品久久夜| 欧美一区二区黄| 性久久久久久久久久久久| 国产一区二三区| 久热爱精品视频线路一| 噜噜噜躁狠狠躁狠狠精品视频| 91久久线看在观草草青青| 亚洲激情一区| 国产精品地址| 久久精品男女| 久久久久成人精品| 亚洲免费观看视频| 一区二区三区高清不卡| 国产精品一区二区三区四区 | 欧美一区在线看| 久久国产精品久久久久久久久久| 在线免费观看成人网| 亚洲激情一区二区三区| 欧美亚男人的天堂| 久久久久久国产精品一区| 久久久夜夜夜| 在线视频你懂得一区二区三区| 中文国产成人精品久久一| 国产亚洲欧洲一区高清在线观看 | 国产精品a级| 欧美在线播放一区| 久久只有精品| 中文日韩在线视频| 欧美一级播放| 日韩图片一区| 欧美一区二区黄色| 99re66热这里只有精品3直播| 亚洲主播在线观看|