小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

MFC的Main函數(shù)跑哪去了

 ThinkTank_引擎 2015-03-10

習慣的思維

用習慣了C的人要看一個程序時首先會想到找到那個main函數(shù)在哪,然后再順著往下看.因為main函數(shù)作為程序的入口點,整個程序都是從那開始執(zhí)行的.當在C++中SDK(win32 API project)開發(fā)時也繼承沿用C的思維,是有個main函數(shù),不過現(xiàn)在的main函數(shù)改名字了,叫WinMain,當然有時還有變體,比如叫_tWinMain,反正名字中總會帶個Main,讓我們一看就知道.而在QT中就跟C一樣,就老實的來個標準的main函數(shù).

我們會發(fā)現(xiàn)C++中可以有一個單獨的main函數(shù),不用包含在哪個類中,另外還有不屬于任何類的全局變量或全局函數(shù)這自然就不是純粹的面向?qū)ο笳Z言了.所以說C++支持多種編程范式嘛,可以是跟C完全一樣的面向過程范式,或者再加些普通的類就是基于對象的范式了,如果再用到繼承和多態(tài)就是面向?qū)ο罅?而要是用到模板就是泛型范式了.而且這些范式可以互相混合用.而C#就是純的面向?qū)ο?所以它里面雖然也有main函數(shù),但也是要放在一個類里面去,至于具體放哪個類無所謂,你隨便放.一般默認是放Program這個類里.當然并不是說純的面向?qū)ο缶捅然旌系姆妒胶?應(yīng)該各有優(yōu)缺點.

哎扯得有點遠了,言歸正傳.

 

SDK中的流程

開發(fā)一個帶界面的SDK程序大致流程是這樣的.首先自然是要有個main函數(shù)做入口點.然后按下面的步驟來(為了討論方便,只說大概流程,代碼也是不完整的)

int _tWinain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)

{

   MSG msg;

   InitApplicatio(HINSTANCE hInstance)   //第1步,注冊窗體類,并在這里指定了窗體過程WndProc

   InitInstance(HINSTANCE hInstance, int nCmdShow)   //第2步,創(chuàng)建窗體

while (GetMessage(&msg, NULL, 0, 0))    //第3步消息循環(huán),分派消息

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

return (int) msg.wParam;  //第4步,退出程序

}

BOOL InitApplicatio(HINSTANCE hInstance)

{

  return RegisterClass(...);

}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)

{

CreateWindow(...); //創(chuàng)建窗體

ShowWindow(...); //顯示窗體

UpdateWindow(...); //送出WM_PAINT

return TRUE;

}

LRESULT CALLBACK WndProc(...){ }

 

在MFC中生成一個有界面的程序大體過程也一樣,只不過封裝起來了.那我們感興趣的就是兩個問題.

1.MFC中有沒有main函數(shù)了,如果有它跑哪去了? 

2.如果有main函數(shù),它里面的那4步涉及到的具體操作是否也跟win32 API一樣?

下面我們就來一一解答下

 

MFC封裝背后流程

 

實際上候捷那本深入淺出MFC里面有講的很清楚了.不過由于講的太詳細了,有幾十頁,看的容易暈,而且他舉的例都是老版本的MFC類,在新版本中一些類的函數(shù)會有一點點變化.

我這里就只概括的講下最簡潔的流程.先假如有類CMyApp繼承自CWinApp吧

 

1.針對第一個問題,MFC里是有用到main函數(shù)的

// export WinMain to force linkage to this module

extern int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

_In_ LPTSTR lpCmdLine, int nCmdShow);

就是這一個函數(shù),在MFC的源文件appmodul.cpp中能看到這些代碼,那這個main怎么被MFC調(diào)用的呢,你看那注釋,是linkage to this module,也就是被鏈接器去調(diào)用的.準確說是被C-Runtime DLL,C運行時動態(tài)鏈接庫調(diào)用的.

調(diào)用main的順序

我們知道在MFC中能從代碼里看到的入口點是定義一個全局的繼承于CWinApp的類.比如CMyApp theApp;這樣定義下.在C++中全局變量是先于main被執(zhí)行的,所以先初始化theApp后才接著調(diào)用main

 

2.針對第2個問題,main函數(shù)里具體的操作.

知道了有main函數(shù),你心里可能有一絲安慰了.但還是有些覺得不安的是這main函數(shù)里的具體操作是否跟SDK中的一樣,是不是也來那么幾步,先注冊窗口再創(chuàng)建窗口之類的.

答案是MFC調(diào)用的main函數(shù)大概流程差不多是那樣,但實現(xiàn)細節(jié)很不一樣.我們看下上面說的AfxWinMain里面的內(nèi)容是啥吧.你可以在winmain.cpp中看到詳細代碼.

把這個main函數(shù)簡化一下,做的操作大概是這樣,

AfxWinMain(...)

{

  //先通過一個全局函數(shù)獲得CWinApp和CWinThread的指針,因為調(diào)用main之前已經(jīng)初始化了這兩個類.CMyApp初始化時也會初始化他的父類CWinApp,及父類的父類CWinThread

   CWinThread* pThread = AfxGetThread(); 

   CWinApp* pApp = AfxGetApp();

 

    //這下面幾個函數(shù)就差不多是完成前面講的SDK中的所有步驟

   pApp->InitApplication();

    pThread->InitInstance();

    pThread->Run();

 

    AfxWinTerm(); //結(jié)束程序

   }

反正結(jié)束程序我們就不用管了,重點關(guān)心前面的三步,注冊窗口,創(chuàng)建窗口,還有消息分派.

前面的SDK程序中也恰好有函數(shù)InitApplication 注冊窗口, InitInstance創(chuàng)建并顯示窗口.而Run函數(shù)你猜想可能是分派消息的..其實大體思路還是沒錯,但實現(xiàn)細節(jié)還是有蠻多區(qū)別.

pApp->InitApplication();這函數(shù)實際上并沒有注冊窗口.注冊窗口,創(chuàng)建顯示窗口全是在pThread->InitInstance();這函數(shù)中完成,InitInstance是個虛函數(shù),而且我們在自己的代碼中會重寫它.所以最后調(diào)用的是我們自己寫的那個InitInstance函數(shù),這就是面向?qū)ο罄锒鄳B(tài)的功能了啊.你指針最終指向?qū)?yīng)的子類定義的函數(shù).

BOOL CMyApp::InitInstance()

{

 m_pMainWnd = new CMyFrameWnd; //這張操作會注冊并創(chuàng)建窗口,m_pMainWnd就是返回的窗口句柄

m_pMainWnd->ShowWindow(m_nCmdShow); //顯示窗口

m_pMainWnd->UpdateWindow();

}

 

pThread->Run();是分派消息,你可以在thrdcore.cpp中查看CWinThreed的run函數(shù)的源碼,下面摘了一點點.

// acquire and dispatch messages until a WM_QUIT message is received.

for (;;)

{}

不過關(guān)于消息的處理MFC用到了消息映射機制,比如復(fù)雜.這里不討論了,反正大概就把CMyFrameWnd當成是窗口過程就行了.

 

MFC怎么封裝CreateWindow見: http://blog.csdn.net/weiwenhp/article/details/8796337

總結(jié)起來可以這樣簡單的說,MFC中有main函數(shù),但是由系統(tǒng)去調(diào)用.然后main函數(shù)里面執(zhí)行的操作差不多,只不過它是通過CWinApp和CWinThread的指針去調(diào)用一些相關(guān)的函數(shù).而指針嘛由于調(diào)用了虛函數(shù),所以用到了面向?qū)ο笾械亩鄳B(tài),于是轉(zhuǎn)來轉(zhuǎn)去的.然后最難的地方可能就是消息機制在這里更復(fù)雜一點了.不能簡單的與SDK中做一對一的對比.

 

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多