mfc编程 孙鑫_孙鑫VC++视频教程笔记-(3)MFC程序框架的剖析 附1-SDI程序流程图
1,尋找WinMain人口:
在安裝目錄下找到MFC文件夾下的SRC文件夾,SRC下是MFC源代碼。
路徑:MFC|SRC|APPMODUL.CPP:
_tWinMain(HINSTANCE?hInstance,?HINSTANCE?hPrevInstance,
LPTSTR?lpCmdLine,?int?nCmdShow)
{
//?call?shared/exported?WinMain
return?AfxWinMain(hInstance,?hPrevInstance,?lpCmdLine,?nCmdShow);
}
注意:(#define?_tWinMain?WinMain)
2,對(duì)于全局對(duì)象或全局變量來(lái)說(shuō),在程序運(yùn)行即WINMAIN函數(shù)加載的時(shí)候,已經(jīng)為全局對(duì)象或全局變量分配了內(nèi)存和賦初值。
所以:CTEApp?theApp;->CTEApp?::CTEApp(){}->_tWinMain(){}
說(shuō)明:每一個(gè)MFC程序,有且只有一個(gè)從WinApp類(lèi)派生的類(lèi)(應(yīng)用程序類(lèi)),也只有一個(gè)從應(yīng)用程序類(lèi)所事例化的對(duì)象,表示應(yīng)用程序本身
。在WIN32程序當(dāng)中,表示應(yīng)用程序是通過(guò)WINMAIN入口函數(shù)來(lái)表示的(通過(guò)一個(gè)應(yīng)用程序的一個(gè)事例號(hào)這一個(gè)標(biāo)識(shí)來(lái)表示的)。在基于MFC應(yīng)用
程序中,是通過(guò)產(chǎn)生一個(gè)應(yīng)用程序?qū)ο?#xff0c;用它來(lái)唯一的表示了應(yīng)用程序。
3,通過(guò)構(gòu)造應(yīng)用程序?qū)ο筮^(guò)程中調(diào)用基類(lèi)CWinApp的構(gòu)造函數(shù),在CWinApp的構(gòu)造函數(shù)中對(duì)程序包括運(yùn)行時(shí)一些初始化工作完成了。
CWinApp構(gòu)造函數(shù):MFC|SRC|APPCORE.CPP
CWinApp::CWinApp(LPCTSTR?lpszAppName){...}//帶參數(shù),而CTEApp構(gòu)造函數(shù)沒(méi)有顯式向父類(lèi)傳參,難道CWinApp()有默認(rèn)參數(shù)?見(jiàn)下:
(在CWinApp類(lèi)定義中,CWinApp(LPCTSTR?lpszAppName?=?NULL);)
注意:CWinApp()函數(shù)中:
pThreadState->m_pCurrentWinThread?=?this;
pModuleState->m_pCurrentWinApp?=?this
(this指向的是派生類(lèi)CTEApp對(duì)象,即theApp)
調(diào)試:CWinApp::CWinApp();->CTEApp?theApp;(->CTEApp?::CTEApp())->CWinApp::CWinApp()->CTEApp?::CTEApp()->_tWinMain(){}
4,_tWinMain函數(shù)中通過(guò)調(diào)用AfxWinMain()函數(shù)來(lái)完成它要完成的功能。(Afx*前綴代表這是應(yīng)用程序框架函數(shù),是一些全局函數(shù),應(yīng)用程序
框架是一套輔助生成應(yīng)用程序的框架模型,把一些類(lèi)做一些有機(jī)的集成,我們可根據(jù)這些類(lèi)函數(shù)來(lái)設(shè)計(jì)自己的應(yīng)用程序)。
AfxWinMain()函數(shù)路徑:MFC|SRC|WINMAIN.CPP:
在AfxWinMain()函數(shù)中:
CWinApp*?pApp?=?AfxGetApp();
說(shuō)明:pApp存儲(chǔ)的是指向WinApp派生類(lèi)對(duì)象(theApp)的指針。
//_AFXWIN_INLINE?CWinApp*?AFXAPI?AfxGetApp()
//?{?return?afxCurrentWinApp;?}
調(diào)用pThread->InitInstance()
說(shuō)明:pThread也指向theApp,由于基類(lèi)中virtual?BOOL?InitApplication()定義為虛函數(shù),所以調(diào)用pThread->InitInstance()時(shí)候,調(diào)用的是
派生類(lèi)CTEApp的InitInstance()函數(shù)。
nReturnCode?=?pThread->Run();
說(shuō)明:pThread->Run()完成了消息循環(huán)。
5,注冊(cè)窗口類(lèi):AfxEndDeferRegisterClass();
AfxEndDeferRegisterClass()函數(shù)所在文件:MFC|SRC|APPCORE.CPP
BOOL?AFXAPI?AfxEndDeferRegisterClass(LONG?fToRegister){...}
說(shuō)明:設(shè)計(jì)窗口類(lèi):在MFC中事先設(shè)計(jì)好了幾種缺省的窗口類(lèi),根據(jù)不同的應(yīng)用程序的選擇,調(diào)用AfxEndDeferRegisterClass()函數(shù)注冊(cè)所選擇的窗口類(lèi)。
調(diào)試:
CWinApp::CWinApp();->CTEApp?theApp;(->CTEApp?::CTEApp())->CWinApp::CWinApp()->CTEApp?::CTEApp()->_tWinMain(){}//進(jìn)入程序
->AfxWinMain();->pApp->InitApplication();->pThread->InitInstance()//父類(lèi)InitInstance虛函數(shù);
->CTEApp::InitInstance()//子類(lèi)實(shí)現(xiàn)函數(shù);
->AfxEndDeferRegisterClass(LONG?fToRegister)//注冊(cè)所選擇的窗口類(lèi)(出于文檔管理,注冊(cè)提前,正常的應(yīng)在PreCreateWindow中進(jìn)行注冊(cè)
)//之后進(jìn)入創(chuàng)建窗口階段(以下再不做調(diào)試)
6,PreCreateWindow()://主要是注冊(cè)窗口類(lèi)
BOOL?CMainFrame::PreCreateWindow(CREATESTRUCT&?cs)
{
if(?!CFrameWnd::PreCreateWindow(cs)?)
return?FALSE;
return?TRUE;
}
說(shuō)明:
CFrameWnd::PreCreateWindow()函數(shù)所在文件:MFC|SRC|WINFRM.CPP
BOOL?CFrameWnd::PreCreateWindow(CREATESTRUCT&?cs)
{
if?(cs.lpszClass?==?NULL)
{
VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG));
//判斷AFX_WNDFRAMEORVIEW_REG型號(hào)窗口類(lèi)是否注冊(cè),如果沒(méi)有注冊(cè)則注冊(cè)
cs.lpszClass?=?_afxWndFrameOrView;?//?COLOR_WINDOW?background
//把注冊(cè)后的窗口類(lèi)名賦給cs.lpszClass
}
if?((cs.style?&?FWS_ADDTOTITLE)?&&?afxData.bWin4)
cs.style?|=?FWS_PREFIXTITLE;
if?(afxData.bWin4)
cs.dwExStyle?|=?WS_EX_CLIENTEDGE;
return?TRUE;
}
其中:
virtual?BOOL?PreCreateWindow(CREATESTRUCT&?cs);//PreCreateWindow()是個(gè)虛函數(shù),如果子類(lèi)有則調(diào)用子類(lèi)的。
#define?VERIFY(f)?ASSERT(f)
#define?AfxDeferRegisterClass(fClass)?AfxEndDeferRegisterClass(fClass)
define?AFX_WNDFRAMEORVIEW_REG?0x00008
const?TCHAR?_afxWndFrameOrView[]?=?AFX_WNDFRAMEORVIEW;//WINCORE.CPP文件中,定義為全局?jǐn)?shù)組。
//#define?AFX_WNDFRAMEORVIEW?AFX_WNDCLASS("FrameOrView")
7,創(chuàng)建窗口:
Create()函數(shù)路徑:MFC|SRC|WINFRM.CPP:
CFrameWnd::Create(...){
...
CreateEx(...);//從父類(lèi)繼承來(lái)的,調(diào)用CWnd::CreateEx().
...
}
CWnd::CreateEx()函數(shù)路徑:MFC|SRC|WINCORE.CPP
BOOL?CWnd::CreateEx(...){
...
if?(!PreCreateWindow(cs))//虛函數(shù),如果子類(lèi)有調(diào)用子類(lèi)的。
{
PostNcDestroy();
return?FALSE;
}
...
HWND?hWnd?=?::CreateWindowEx(cs.dwExStyle,?cs.lpszClass,
cs.lpszName,?cs.style,?cs.x,?cs.y,?cs.cx,?cs.cy,
cs.hwndParent,?cs.hMenu,?cs.hInstance,?cs.lpCreateParams);
...
}
說(shuō)明:CreateWindowEx()函數(shù)與CREATESTRUCT結(jié)構(gòu)體參數(shù)的對(duì)應(yīng)關(guān)系,使我們?cè)趧?chuàng)建窗口之前通過(guò)可PreCreateWindow(cs)修改cs結(jié)構(gòu)體成員來(lái)
修改所要的窗口外觀。PreCreateWindow(cs))//是虛函數(shù),如果子類(lèi)有調(diào)用子類(lèi)的。
HWND?CreateWindowEx(
DWORD?dwExStyle,
LPCTSTR?lpClassName,
LPCTSTR?lpWindowName,
DWORD?dwStyle,
int?x,
int?y,
int?nWidth,
int?nHeight,
HWND?hWndParent,
HMENU?hMenu,
HINSTANCE?hInstance,
LPVOID?lpParam
);
typedef?struct?tagCREATESTRUCT?{?//?cs
LPVOID?lpCreateParams;
HINSTANCE?hInstance;
HMENU?hMenu;
HWND?hwndParent;
int?cy;
int?cx;
int?y;
int?x;
LONG?style;
LPCTSTR?lpszName;
LPCTSTR?lpszClass;
DWORD?dwExStyle;
}?CREATESTRUCT;
8,顯示和更新窗口:
CTEApp類(lèi),TEApp.cpp中
m_pMainWnd->ShowWindow(SW_SHOW);//顯示窗口,m_pMainWnd指向框架窗口
m_pMainWnd->UpdateWindow();//更新窗口
說(shuō)明:
class?CTEApp?:?public?CWinApp{...}
class?CWinApp?:?public?CWinThread{...}
class?CWinThread?:?public?CCmdTarget
{?...
public:
CWnd*?m_pMainWnd;
...}
9,消息循環(huán):
int?AFXAPI?AfxWinMain()
{?...
//?Perform?specific?initializations
if?(!pThread->InitInstance()){...}
//完成窗口初始化工作,完成窗口的注冊(cè),完成窗口的創(chuàng)建,顯示和更新。
nReturnCode?=?pThread->Run();
//繼承基類(lèi)Run()方法,調(diào)用CWinThread::Run()來(lái)完成消息循環(huán)...
}
CWinThread::Run()方法路徑:MFC|SRC|THRDCORE.CPP
int?CWinThread::Run()
{?...
//?phase2:?pump?messages?while?available
do//消息循環(huán)
{
//?pump?message,?but?quit?on?WM_QUIT
if?(!PumpMessage())//取消息并處理
return?ExitInstance();?...
}?while?(::PeekMessage(&m_msgCur,?NULL,?NULL,?NULL,?PM_NOREMOVE));
...
}
說(shuō)明:
BOOL?PeekMessage(,,,,)函數(shù)說(shuō)明
The?PeekMessage?function?checks?a?thread?message?queue?for?a?message?and?places?the?message?(if?any)?in?the?specified
structure.
If?a?message?is?available,?the?return?value?is?nonzero.
If?no?messages?are?available,?the?return?value?is?zero.
/
BOOL?CWinThread::PumpMessage()
{?...
if?(!::GetMessage(&m_msgCur,?NULL,?NULL,?NULL))//取消息
{...}?...
//?process?this?message
if?(m_msgCur.message?!=?WM_KICKIDLE?&&?!PreTranslateMessage(&m_msgCur))
{
::TranslateMessage(&m_msgCur);//進(jìn)行消息(如鍵盤(pán)消息)轉(zhuǎn)換
::DispatchMessage(&m_msgCur);//分派消息到窗口的回調(diào)函數(shù)處理(實(shí)際上分派的消息經(jīng)過(guò)消息映射,交由消息響應(yīng)函數(shù)進(jìn)行處理。)
}
return?TRUE;
}
10,文檔與視結(jié)構(gòu):
可以認(rèn)為View類(lèi)窗口是CMainFram類(lèi)窗口的子窗口。
DOCument類(lèi)是文檔類(lèi)。
DOC-VIEW結(jié)構(gòu)將數(shù)據(jù)本身與它的顯示分離開(kāi)。
文檔類(lèi):數(shù)據(jù)的存儲(chǔ),加載
視類(lèi):數(shù)據(jù)的顯示,修改
11,文檔類(lèi),視類(lèi),框架類(lèi)的有機(jī)結(jié)合:
在CTEApp類(lèi)CTEApp::InitInstance()函數(shù)中通過(guò)文檔模板將文檔類(lèi),視類(lèi),框架類(lèi)的有機(jī)組織一起。...
CSingleDocTemplate*?pDocTemplate;
pDocTemplate?=?new?CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CTEDoc),
RUNTIME_CLASS(CMainFrame),?//?main?SDI?frame?window
RUNTIME_CLASS(CTEView));
AddDocTemplate(pDocTemplate);//增加到模板...
----------------------------------------------------------------------------->
//AfxWinMain()函數(shù)在WINMAIN.CPP文件中,它主要調(diào)用以下函數(shù)
AfxWinInit();
pApp->InitApplication();?//內(nèi)部初始化管理
pThread->InitInstance();?//調(diào)用子類(lèi)中的InitInstance()
CTestApp::InitInstance();
┣━ProcessShellCommand(cmdInfo);?//對(duì)命令行進(jìn)行解釋
┃?CTestDoc::CTestDoc();?//構(gòu)造文檔類(lèi)對(duì)象
┃?CMainFrame::CMainFrame();?//構(gòu)造框架窗口對(duì)象
┃?CFrameWnd::LoadFrame();?//WINFRM.CPP
┃?┣━AfxEndDeferRegisterClass();?//WINCORE.CPP,注冊(cè)窗口類(lèi)
┃?┃?AfxRegisterClass();?//WINCORE.CPP
┃?┣━CMainFrame::PreCreateWindow();
┃?┃?CFrameWnd::PreCreateWindow();
┃?┃?AfxEndDeferRegisterClass();
┃?┣━AfxRegisterClass();
┃?┗━CFrameWnd::Create();?//創(chuàng)建CMainFrame窗口
┃?CWnd::CreateEx();
┃?CMainFrame::PreCreateWindow();
┃?CFrameWnd::PreCreateWindow();
┃?CTestView::CTestView();?//構(gòu)造CTestView對(duì)象
┃?CWnd::CreateEx();?//創(chuàng)建CTestView窗口
┃?AfxEndDeferRegisterClass();
┃?AfxEndDeferRegisterClass();
┃?CWnd::CreateEx();?//創(chuàng)建CToolBar工具欄
┃?AfxEndDeferRegisterClass();
┃?CWnd::CreateEx();?//創(chuàng)建CStatusBar狀態(tài)欄
┃?AfxEndDeferRegisterClass();
┃?AfxRegisterClass();
┃?CWnd::CreateEx();?//創(chuàng)建CDockBar
┃?AfxEndDeferRegisterClass();
┃?CWnd::CreateEx();?//創(chuàng)建CDockBar
┃?AfxEndDeferRegisterClass();
┃?CWnd::CreateEx();?//創(chuàng)建CDockBar
┃?AfxEndDeferRegisterClass();
┃?CWnd::CreateEx();?//創(chuàng)建CDockBar
┣━m_pMainWnd->ShowWindow(SW_SHOW);?//顯示窗口
┗━m_pMainWnd->UpdateWindow();?//更新窗口
nReturnCode?=?pThread->Run();?//進(jìn)入消息循環(huán)
總結(jié)
以上是生活随笔為你收集整理的mfc编程 孙鑫_孙鑫VC++视频教程笔记-(3)MFC程序框架的剖析 附1-SDI程序流程图的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: oracle 取mac地址,java执行
- 下一篇: C++求复数的角度_【研读.教材分析】“