日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

MFC 学习笔记(一):MFC单文档程序运行流程梳理与总结

發(fā)布時間:2024/7/23 编程问答 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MFC 学习笔记(一):MFC单文档程序运行流程梳理与总结 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

MFC 學(xué)習(xí)筆記(一):MFC單文檔程序運行流程梳理與總結(jié)

1.MFC單文檔程序運行流程

1.首先利用全局變量對象 theApp 啟動應(yīng)用程序
(這是因為這個全局對象,基類CWinApp中 this 的指針才能指向這個對象。)

2.調(diào)用全局應(yīng)用程序?qū)ο?theApp 的構(gòu)造函數(shù)
(需要先調(diào)用其基類CWinApp的構(gòu)造函數(shù),
完成應(yīng)用程序的一些初始化工作,并將應(yīng)用程序?qū)ο蟮闹羔槺4嫫饋怼?#xff09;

3.進入WinMain函數(shù)
(CWinApp的構(gòu)造函數(shù)中調(diào)用 AfxWinMain 函數(shù))

4.調(diào)用虛函數(shù):InitInstance()
(利用在AfxWinMain函數(shù)中可以獲取子類的指針,并調(diào)用InitInstance函數(shù) 如下圖)
(③ 指令實際上調(diào)用的是子類(CTestApp)的InitInstance函數(shù))



5.子類(CTestApp)中的InitInstance()函數(shù)完成應(yīng)用程序的一些初始化工作
(包括窗口類的注冊,創(chuàng)建,窗口的顯示和更新。
期間會多次調(diào)用CreateEX函數(shù),因為一個單文檔MFC應(yīng)用程序有多個窗口,包括框架窗口.工具條.狀態(tài)條等。)

初始化舉例
例如:
1)CTestApp::Initstance()函數(shù)中定義了一個單文檔模板對象指針,
2)該對象就把文檔類對象、框架類對象、視窗類對象有機地組織在一起,
3)接著利用AddDocTemplate函數(shù)把這個單文檔模板添加到文檔模板中,從而把這個三個類組織成為一個整體,如圖:

又如:
1)m_pMainWnd 表示指向程序框架窗口的指針(CMainFrame)
2)通過該指針顯示和更新程序框架窗口

4.進入消息循環(huán)。
上圖:pThread->Run()
(雖然也設(shè)置了默認的窗口過程函數(shù),但是,MFC應(yīng)用程序?qū)嶋H上是采用消息映射機制來處理各種消息。當收到WM_QUIT消息時,退出消息循環(huán),程序結(jié)束。)

參考博客:
https://blog.csdn.net/c_base_jin/article/details/52345563

PS:
1.Afx前綴的函數(shù)代表應(yīng)用程序框架(Application Framework)函數(shù),屬于全局函數(shù),它們可以在程序的任何地方被調(diào)用。
2.以域作用符“::”開始的表示的函數(shù),表明該函數(shù)是一個全局函數(shù)。

2.總結(jié)補充

1.由于theApp是全局對象,因此會在進入WinMain()之前完成構(gòu)造
theApp的構(gòu)造動作會導(dǎo)致一系列的對theApp的初始化動作:

pModuleState->m_pCurrentWinApp = this;

2.接著進入WinMain()
WinMain()(_tWinMain(),這是為了UniCode而準備的一個宏)直接調(diào)用AfxWinMain(),AfxWinMain()發(fā)揮真正應(yīng)該由WinMain()發(fā)揮的作用,它取得theApp,然后必須先調(diào)用AfxWinInit(),再用取得的指向theApp的指針pApp調(diào)用InitApplication()、InitInstance()和Run(),最后調(diào)用AfxWinTerm()終止程序。
即AfxWinMain()中的動作相當于:

AfxWinInit(); CWinApp::InitApplication(); CMyWinApp::InitInstance(); CWinApp::Run();

3.AfxWinInit()做什么?
首先將WinMain()傳進來的四個參數(shù)保留在theApp的成員變量里。
調(diào)用AfxInitThread(),此函數(shù)又調(diào)用::SetWindowHookEx(),不知干啥。另外此函數(shù)還將消息隊列盡量加大到96。

4.CWinApp::InitApplication()做什么?
會做一些與CDocManager()和Document Template相關(guān)的工作,是MFC的內(nèi)部管理范疇。

5.CMyWinApp::InitInstance()做什么?
終于來到了我們可以改寫的InitInstance(),這個函數(shù)是CWinApp的虛函數(shù),CMyWinApp通常要改寫它,其實在CWinApp中InitInstance()是一個空函數(shù)。
InitInstance()的動作如下:

m_pMainWnd = new CMyFrameWnd(); m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow();

【(InitInstance()首先會創(chuàng)建一個CMyFrameWnd對象,并將指針保留在m_pMainWnd中。這個CMyFrameWnd對象的創(chuàng)建過程就會導(dǎo)致主窗口的登記和建立,因為CFrameWnd的構(gòu)造函數(shù)中會調(diào)用Create()函數(shù),而這個函數(shù)負責創(chuàng)建窗口(通過調(diào)用CreateWindowEx),窗口風(fēng)格使用最常見的WS_OVERLAPPEDWINDOW。
但是這僅僅是創(chuàng)建窗口,窗口類注冊的動作(必須先于窗口的創(chuàng)建)又發(fā)生在哪里呢?
其實Create()的調(diào)用會導(dǎo)致CWnd::CreateEx()的調(diào)用,此函數(shù)才是真正調(diào)用CreateWindowEx()創(chuàng)建窗口者,在調(diào)用CreateWindowEx()之前會調(diào)用CFrameWnd::PreCreateWindow(),此函數(shù)判斷傳入的窗口類名lpszClassName是否為NULL,若是,則通過一系列的調(diào)用(非常之繞)為其注冊默認窗口類別。由于每個窗口創(chuàng)建過程中PreCreateWindow()都只在創(chuàng)建之前被調(diào)用,因此窗口的注冊大多在創(chuàng)建之前發(fā)生。CWnd及其派生類的各個不同)

PreCreateWindow()函數(shù)為不同窗口指定了不同的默認窗口類別:
CWnd使用的窗口類別是_afxWnd
CFrameWnd和CMDIChildWnd使用的窗口類別是_afxWndFrameOrView
CMDIFrameWnd使用的窗口類別是_afxWndMDIFrame】

綜上,InitInstance()中的第一個動作――創(chuàng)建CMyFrameWnd對象――完成了窗口的創(chuàng)建。之后的動作就很直觀了,ShowWindow()顯示窗口,UpdateWindow()發(fā)送WM_PAINT消息更新窗口。

6.回到AfxWinMain()中,接下來執(zhí)行的是CWinApp::Run()。
Run()所做的正是維持程序運行的“消息循環(huán)”。CWinApp::Run()會調(diào)用CWinThread::Run(),此Run()中有消息循環(huán),通過PumpMessage()得到并轉(zhuǎn)發(fā)消息(調(diào)用::GetMessage()、::TranslateMessage()、::DispatchMessage(),一如SDK!)。
**但是轉(zhuǎn)發(fā)到哪里呢?窗口函數(shù)呢?**原來在MFC為我們注冊默認窗口類的時候已經(jīng)指定了窗口函數(shù)為DefWindowProc(),但是真正處理消息的又不是它,而是一個全局函數(shù)AfxWndProc(),這是MFC通過hook和subclassing技術(shù)做到的,暫且不提。

綜上,MFC為我們的程序提供了WinMain()、注冊了窗口類、創(chuàng)建了窗口甚至提供了窗口函數(shù),留給我們做的只是寫出響應(yīng)消息的處理函數(shù),而這些消息和處理函數(shù)如何對應(yīng)起來還要靠MFC六大關(guān)鍵技術(shù)之一的Message Mapping(消息映射)。消息映射機制的目的是首先搭建起消息和消息處理函數(shù)對應(yīng)的大框架,再通過宏的機制讓程序員能夠方便地添加消息和消息處理函數(shù)之間的對應(yīng)關(guān)系。

7.在程序運行的過程中,程序不斷地由消息所驅(qū)動,直到用戶動作發(fā)出了WM_CLOSE消息,程序即將關(guān)閉
過程是:由于CMyFrameWnd沒有設(shè)立WM_CLOSE的處理函數(shù),因此該消息被送往預(yù)設(shè)處理函數(shù),預(yù)設(shè)函數(shù)對WM_CLOSE的處理是調(diào)用::DestroyWindow(),進而發(fā)送WM_DESTROY消息,WM_DESTROY消息同樣會被送到預(yù)設(shè)處理函數(shù),預(yù)設(shè)函數(shù)對WM_DESTROY的處理方法是調(diào)用::PostQuitMessage(),發(fā)送WM_QUIT,CWinApp::Run()在收到WM_QUIT后會結(jié)束自己的消息循環(huán),并調(diào)用ExitInstance(),這是CWinApp的虛函數(shù),可被CMyWinApp改寫,調(diào)用過此函數(shù)后,回到AfxWinMain()中調(diào)用AfxWinTerm()結(jié)束程序。

總結(jié)

以上是生活随笔為你收集整理的MFC 学习笔记(一):MFC单文档程序运行流程梳理与总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。