預設情況下,c語言一般都有main函式,可是在mfc程式裡面我們一般會發現不了main函式,其實這個是有的。
注意:預設情況下。如在嵌入式領域,無論怎麼啟動,最終都會跳到乙個迴圈程式,當出現正常退出或者異常才會退出這個迴圈,執行緒處理函式一樣,所以main還是_tmain都是我們定義的入口函式,當然os或者庫也可以定義其他的,這個主函式其實只是乙個入口點。
看乙個簡單的c程式
int main(int argc, char *argv)
這裡會有傳入引數,執行迴圈體,返回語句
當然在window sdk程式設計中也會出現這個的,因為sdk程式設計一般都是自己建立視窗,以下在vs2012自動生成的**,在繪圖處理**中加入了hello的顯示
// hello.cpp : 定義應用程式的入口點。
//#include "stdafx.h"
#include "hello.h"
#define max_loadstring 100
// 全域性變數:
hinstance hinst; // 當前例項
tchar sztitle[max_loadstring]; // 標題欄文字
tchar szwindowclass[max_loadstring]; // 主視窗類名
// 此**模組中包含的函式的前向宣告:
atom myregisterclass(hinstance hinstance);
bool initinstance(hinstance, int);
lresult callback wndproc(hwnd, uint, wparam, lparam);
int_ptr callback about(hwnd, uint, wparam, lparam);
int apientry _twinmain(_in_ hinstance hinstance,
_in_opt_ hinstance hprevinstance,
_in_ lptstr lpcmdline,
_in_ int ncmdshow)
...// 主訊息迴圈:
while (getmessage(&msg, null, 0, 0)) //獲取訊息到msg,並從佇列中刪除它,沒有退出 }
return (int) msg.wparam;}//
// 函式: myregisterclass()
//// 目的: 註冊視窗類。
//atom myregisterclass(hinstance hinstance)
//// 函式: initinstance(hinstance, int)
//// 目的: 儲存例項控制代碼並建立主視窗
bool initinstance(hinstance hinstance, int ncmdshow)
showwindow(hwnd, ncmdshow);
updatewindow(hwnd);
return true;}//
// 函式: wndproc(hwnd, uint, wparam, lparam)
//// 目的: 處理主視窗的訊息。
//// wm_command - 處理應用程式選單
// wm_paint - 繪製主視窗
// wm_destroy - 傳送退出訊息並返回
////
lresult callback wndproc(hwnd hwnd, uint message, wparam wparam, lparam lparam)
case wm_destroy:
postquitmessage(0);
break;
default:
return defwindowproc(hwnd, message, wparam, lparam);
} return 0;
}
精簡以上main函式**
1. 註冊視窗類,包含一些公共的視窗類的一些屬性:atom myregisterclass(hinstance hinstance)
2. 建立視窗並顯示:bool initinstance(hinstance hinstance, int ncmdshow)
3. 獲取訊息並處理訊息:
while (getmessage(&msg, null, 0, 0)) //獲取訊息到msg,並從佇列中刪除它,沒有退出}
4. 訊息處理: 裡面使用了switch對不同的訊息進行處理:lresult callback wndproc(hwnd hwnd, uint message, wparam wparam, lparam lparam);
可以看出以上也是有傳入引數,訊息主體(主要是訊息迴圈處理),返回語句(正常退出或者異常退出)
;
// mfchellodlg.h : 標頭檔案
//#pragma once
// cmfchellodlg 對話方塊
class cmfchellodlg : public cdialogex
;
那麼mfc主函式在**呢?f10除錯後,會跳到主函式_twinmain
extern "c" int winapi
_twinmain(hinstance hinstance, hinstance hprevinstance,
_in_ lptstr lpcmdline, int ncmdshow)
#pragma warning(suppress: 4985)
而afxwinmain在vs安裝目錄就有,例如我的安裝目錄
c:\program files (x86)\vs 2012\vc\atlmfc\src\mfc\winmain.cpp
在這個檔案裡,如下
int afxapi afxwinmain(hinstance hinstance, hinstance hprevinstance,
_in_ lptstr lpcmdline, int ncmdshow)
nreturncode = pthread->exitinstance();
goto initfailure;
}//執行執行緒的迴圈函式
nreturncode = pthread->run();
...//執行緒終止
afxwinterm();
return nreturncode;
}
精簡以上**,就會發現其實是一樣的
1.初始化主框架,儲存引數 : if (!afxwininit(hinstance, hprevinstance, lpcmdline, ncmdshow))
cmfchellodlg dlg;
m_pmainwnd = &dlg;
int_ptr nresponse = dlg.domodal();
4.迴圈處理函式:nreturncode = pthread->run(); run 獲取和計畫windows訊息,直到應用程式收到wm_quit
訊息。 如果執行緒的訊息佇列當前不包含訊息, run 呼叫 onidle 執行空閒時間處理。 傳入訊息轉到處理的特定的pretranslatemessage 成員函式然後標準鍵盤轉換的windows函式translatemessage。 最後dispatchmessage windows函式呼叫。
5. 銷毀應用程式: afxwinterm();這裡包括註冊的視窗類、執行緒模組和執行緒全域性結構體的銷毀
初始化函式的呼叫
在這裡我們似乎沒有發現create建立視窗的過程,怎麼回事,難道沒有??其實不是的,只是我們在第3步的時候遺漏了乙個地方:
cmfchellodlg dlg; //在棧上建立物件,便於退出時釋放(堆上也是可以的,但要退出時進行釋放)
dlg.domodal(); //視窗的顯示
那麼如何呼叫oninitdialog()進行初始化呢?
int_ptr cdialog::domodal()
-》 if (!createrundlgindirect(lpdialogtemplate, cwnd::fromhandle(hwndparent), hinst) && !g_bclosedbyenddialog)
-》bool cwnd::createdlgindirect(lpcdlgtemplate lpdialogtemplate, cwnd* pparentwnd, hinstance hinst)
-》 hwnd = ::createdialogindirect(hinst, lpdialogtemplate,pparentwnd->getsafehwnd(), afxdlgproc);
-》int_ptr callback afxdlgproc(hwnd hwnd, uint message, wparam, lparam)
afxdlgproc函式的**如下:
int_ptr callback afxdlgproc(hwnd hwnd, uint message, wparam, lparam)
return 0;
}
當得到的訊息是wm_initdialog且dlg不為空,就呼叫基類的pdlg->oninitdialog(),這個函式是虛函式而且子類進行了重寫,就會呼叫bool cmfchellodlg::oninitdialog()進行視窗的初始化。
MFC 程式啟動流程分析
一 mfc程式執行過程剖析 相信大家有點暈點了吧,實際程式設計中沒有必要深刻理解這麼多,這些大都是由mfc內部自動幫我們完成的。實際mfc程式設計過程中,其實懂得mfc程式中各個函式的執行流程即可。有時候過於追究mfc細節會白白浪費我們的精力,應該將主要精力放在使用mfc解決實際問題上。二 vc6中...
IsPostBack深入分析
1 ispostback 介紹 ispostback是 page類有乙個 bool型別的屬性,用來判斷針對當前 form的請求是第一次還是非第一次請求。當 ispostback true時表示非第一次請求,我們稱為 postback,當 ispostback false時表示第一次請求。在 asp....
深入分析ConcurrentHashMap
再多執行緒的情況下,如果使用hashmap,就會導致死迴圈,導致cpu利用率接近100 所以如果是併發的情況不要使用hashmap 導致死迴圈主要是這段 當在多執行緒的情況由於沒有同步導致,著段 在擴容的時候會執行 do while e null 執行緒安全的hashtable 容器 hashtab...