為什麼要學Win32及Win32程式架構

來源:互聯網
上載者:User

 前言:

  最近在看侯捷的《深入淺出MFC》,在理解MFC時覺得必須要掌握win32,才能更好的理解MFC,才能寫出更有用的程式。於是將自己對win32程式的理解寫了下來,供朋友們參考。文中的兩幅圖是從書中截取的。

本文:

  現在有很多想走VC這條路的朋友,一開始就是MFC,雖然啃過一段時間書後,能寫出一些小程式,但越往後你就會越覺得困難。我的一個網友昨天跟我聊天的時候說“TMD,MFC用的越來越覺得不爽,早知道開始學VC的時候聽朋友之勸,先學Win32編程好了”。的確,MFC把大部分精華都封裝起來了,我們只能用它現成的庫,或尤其派生出一些自己的庫。如果不瞭解Win32編程,我們就不懂程式的運作原理,那麼我們如何操控程式,我們還哪有自主權?

  如果你從來沒有在事件驅動(event driven)系統中撰寫過以訊息為基礎(message based)的應用程式,就想一步跨入MFC,直接用Application wizard開發windows程式,我覺得不大可能。雖然你可以繼承MFC中的類,來開發出一個頗具規模的windows應用程式,但如果你不瞭解windows程式的運作本質(event driven,message based ),是不可能進入高深境界的。正如侯大師所言:“勿在浮沙築高台”,不會走千萬別想跑。

  在正式學習MFC之前,需要掌握的東西(個人認為)有:瞭解windows程式的事件驅動機制(包括訊息的產生、捕獲、指派和處理等)。另外還有一個比較重要的就是C++中多態(polymorphism)和虛函數的理解(不說精通,起碼也得達到熟練)。

  下面簡單說一下Win32程式架構。

  一個Win32程式是由程式碼和UI(User Interface)兩大部分組成,當我們編輯好這兩部分後,再由RC(resource compiler)編譯器將這兩部分整合成一個EXE檔案。程式碼不用說了,UI資源指的是一些如菜單、對話方塊、位元影像、滑鼠指標、表徵圖等,我們必須在一個.rc檔案中描述它們。

  另外,程式要想成功編譯運行,還需要加入一些函數庫和標頭檔。Windows程式調用的函數可以分為C Runtimes和Windows API兩種,LIBC.LIB是C Runtimes的靜態串連版,MSVCRT.LIB是C Runtimes的動態串連版。GDI32.DLL、USER32.DLL和KERNEL32.DLL是32位Windows API的三大函數庫。所有的windows程式都要包含windows.h,但windows.h只包含GDI32.DLL、USER32.DLL和KERNEL32.DLL中的函數,如果你還想加入別的dll,就需要加入相應的標頭檔。下面是win32程式開發的流程:

 

  Windows程式的運行是靠外來事件來驅動的,就是說,程式一直出於一個等待的狀態,如果有一個事件發生,程式就會判斷是什麼事件,然後做出相應的處理。那麼每一個windows程式都必須有一個迴路才能實現一直等待。這個迴路如下:

MSG msg;

while( GetMessage( &msg, NULL, 0, 0 ) ){

TranslateMessage( &msg );

DispatchMessage( &msg );

}

MSG結構在windows內部是這樣定義的:

typedef struct tagMsg{

HWND hWnd;

UINT message;

WPARAM wParam;

LPARAM lParam;

DWORD time;

POINT pt;

}MSG;

  其中message就是指各種訊息,如WM_MOUSEMOVE、WM_DESTROY等。那麼誰來接收這個訊息並做出相應處理呢?就是視窗,這就需要我們為視窗設計一個函數,即所謂的視窗函數。視窗函數形如:

LRESULT CALLBACK WndProc( HWND hWnd,

UINT message,

WPARAM wParam,

LPARAM lParam)

{

switch ( message ) {

case WM_LBUTTONDOWN:

case WM_MOUSEMOVE:

case WM_DESTROY:

PostQuitMessage ( 0 );

default:

return DefWindowProc ( hWnd, message, wParam, lParam );

}

return ( 0 );

}

  CALLBACK是一種函數調用習慣,被定義為__stdcall,說明此函數為回呼函數,由系統自動調用的,當視窗接收到訊息並DispatchMessage之後,系統就自動調用視窗函數WndProc了。注意視窗函數中訊息的分支結構中default分支必須是return DefWindowProc ( hWnd, message, wParam, lParam );因為不論什麼訊息都必須被處理,DefWindowProc是windows內部預設的訊息處理函數。以上就是windows程式的精要所在,弄懂了這些,才能為學MFC作好準備。Win32程式的運行圖解如下:

 那麼視窗的產生和顯示是怎麼實現的呢?下面我們就來產生一個簡單的win32SDK視窗,來看一下windows程式是如何把訊息擷取、指派並處理的,以及寫一個win32視窗程序的主要步驟:

一、程式進入點

  windows程式的進入點是WinMain函數,它有四個參數,形式如下:

int WINAPI WinMain ( HINSTANCE hInst,

HINSTANCE hPrevInst,

LPSTR lpCmdLine,

int nCmdShow )

  參數說明:hInst 為當前執行個體控制代碼,Windows 環境下用於區別同一應用程式的不同執行個體;hPrevInst應用程式先前執行個體的控制代碼(如果有的話),否則為 NULL,可以用來確定當前執行個體是否為應用程式的第一個執行個體;lpCmdLine是以NULL結尾的命令列字串長指標;nCmdShow指定視窗初始顯示方式的整型常量(1 = 通常;7 = 最小化) 。

二、註冊視窗類別

 一個視窗在建立以前,必須進行一些初始化,比如視窗的大小、標題及邊框的顏色等,完成這些工作我們還必須一個API函數RegisterClass來註冊視窗類別:

WNDCLASS wndclass;

//初始化視窗的屬性

…………….

//註冊視窗類別

if(!RegisterClass(&wndclass))

{

MessageBeep(0);

return FALSE;

}

三、建立視窗

  視窗屬性設定好並且註冊了視窗類別之後,我們就要建立一個視窗了,CreateWindow函數會完成這個工作,如:

hwnd=CreateWindow(

lpszClassName,

lpszTitle,

WS_OVERLAPPEDWINDOW,

CW_USEDEFAULT,

CW_USEDEFAULT,

CW_USEDEFAULT,

CW_USEDEFAULT,

NULL,

NULL,

hInstance,

NULL);

  建立好視窗之後就要顯示視窗了,如下:

  //顯示視窗

  ShowWindow(hwnd,nCmdShow);

UpdateWindow(hwnd);

  然後進步訊息迴圈,程式出於一直等待的狀態(除非你退出程式)。

//訊息迴圈

while(GetMessage(&Msg,NULL,0,0))

{

TranslateMessage(&Msg);

DispatchMessage(&Msg);

}

四、視窗函數

  這是視窗的生命中樞,因為它是處理各種訊息的地方。上面訊息迴圈中DispatchMessage就是將訊息指派到視窗處理函數,視窗處理函數前面已經作了說明,這裡不再贅述。

  這樣,一個win32視窗程序就寫好了,具體詳見附加代碼。

 

 

摘自:http://www.cnblogs.com/michaelxu/archive/2006/09/20/509043.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.