青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品



  盡管Windows應(yīng)用程序千變?nèi)f化,令人眼花繚亂,但,消息機(jī)制和窗口過(guò)程卻始終它們的基礎(chǔ),掌握了這兩項(xiàng)技術(shù),也就相當(dāng)于把握住了問(wèn)題的關(guān)鍵。

  如果你以前是C程序員或是MFC的忠實(shí)用戶,只要你學(xué)習(xí)過(guò)C語(yǔ)言的語(yǔ)法,自己親手編過(guò)一些簡(jiǎn)短的C程序,理解以下的Win32編程基礎(chǔ)也不是一件困難的事。

  一個(gè)最簡(jiǎn)單的Win32程序

  在以前的C語(yǔ)言編程中,一個(gè)最簡(jiǎn)單的程序可以只有兩行。

void main(void)

{ printf "Hello World!"; }

  而要實(shí)現(xiàn)同樣功能的Windows程序卻最少也要寫幾十行,這并不是說(shuō)明Windows應(yīng)用程序效率低下,難于掌握,只是說(shuō)明程序在Windows環(huán)境下有更豐富的內(nèi)涵。Windows程序的效率其實(shí)不低,在所有的Windows應(yīng)用程序中,都有一個(gè)程序初始化的過(guò)程,這得用上幾十條語(yǔ)句,這段初始化的代碼對(duì)于任何Windows應(yīng)用程序而言,都是大同小異的。下面以一個(gè)實(shí)現(xiàn)最簡(jiǎn)單功能的程序EasyWin為例,說(shuō)明Windows程序的基本框架。

  打開(kāi)Visual C++ 6.0。

  選擇File菜單的New,在出現(xiàn)的對(duì)話框中,選擇Projects欄目(新建工程),并點(diǎn)取其下的Win32 Application項(xiàng),表示使用Win32環(huán)境創(chuàng)建應(yīng)用程序。先在Locatin(路徑)中填入“c:\”,然后在Project Name(項(xiàng)目名稱)中填入“EasyWin”,其它按照缺省設(shè)置)。單擊OK按鈕。

  再次選擇File菜單的New,在出現(xiàn)的對(duì)話框中,選擇Files欄目(新建文件),并點(diǎn)取其下的C++ Source File項(xiàng),表示新建一個(gè)C++源文件。在右邊的File欄中輸入“EasyWin”,最后確定讓Add to project檢查框打上勾 )。單擊OK按鈕。



  在EasyWin.cpp文件中輸入以下源程序代碼。  
 
//*******************************************************************
// 工程:easywin
// 文件:easywin.cpp
// 內(nèi)容:一個(gè)基本的Win32程序//*******************************************************************

#include <windows.h>

#include <windowsx.h>

//函數(shù)聲明

BOOL InitWindow( HINSTANCE hInstance, int nCmdShow );

LRESULT CALLBACK WinProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam );

//*******************************************************************

//函數(shù):WinMain()

//功能:Win32應(yīng)用程序入口函數(shù)。創(chuàng)建主窗口,處理消息循環(huán)

//*******************************************************************

int PASCAL WinMain( HINSTANCE hInstance, //當(dāng)前實(shí)例句柄

HINSTANCE hPrevInstance, //前一個(gè)實(shí)例句柄

LPSTR lpCmdLine, //命令行字符

int nCmdShow) //窗口顯示方式

{

MSG msg;

//創(chuàng)建主窗口

if ( !InitWindow( hInstance, nCmdShow ) )

return FALSE;

//進(jìn)入消息循環(huán):

//從該應(yīng)用程序的消息隊(duì)列中檢取消息,送到消息處理過(guò)程,

//當(dāng)檢取到WM_QUIT消息時(shí),退出消息循環(huán)。

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

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

//程序結(jié)束

return msg.wParam;

}

//******************************************************************

//函數(shù):InitWindow()

//功能:創(chuàng)建窗口。

//******************************************************************

static BOOL InitWindow( HINSTANCE hInstance, int nCmdShow )

{

HWND hwnd; //窗口句柄

WNDCLASS wc; //窗口類結(jié)構(gòu)

//填充窗口類結(jié)構(gòu)

wc.style = CS_VREDRAW | CS_HREDRAW;

wc.lpfnWndProc = (WNDPROC)WinProc;

wc.cbClsExtra = 0;

wc.cbWndExtra = 0;

wc.hInstance = hInstance;

wc.hIcon = LoadIcon( hInstance, IDI_APPLICATION );

wc.hCursor = LoadCursor( NULL, IDC_ARROW );

wc.hbrBackground = GetStockObject(WHITE_BRUSH);

wc.lpszMenuName = NULL;

wc.lpszClassName = "EasyWin";

//注冊(cè)窗口類

RegisterClass( &wc );

 

//創(chuàng)建主窗口

hwnd = CreateWindow(

"EasyWin", //窗口類名稱

"一個(gè)基本的Win32程序", //窗口標(biāo)題

WS_OVERLAPPEDWINDOW, //窗口風(fēng)格,定義為普通型

100, //窗口位置的x坐標(biāo)

100, //窗口位置的y坐標(biāo)

400, //窗口的寬度

300, //窗口的高度

NULL, //父窗口句柄

NULL, //菜單句柄

hInstance, //應(yīng)用程序實(shí)例句柄

NULL ); //窗口創(chuàng)建數(shù)據(jù)指針

if( !hwnd ) return FALSE;

//顯示并更新窗口

ShowWindow( hwnd, nCmdShow );

UpdateWindow( hwnd );

return TRUE;

}

//******************************************************************

//函數(shù):WinProc()

//功能:處理主窗口消息

//******************************************************************

LRESULT CALLBACK WinProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )

{

switch( message )

{

case WM_KEYDOWN://擊鍵消息

switch( wParam )

{

case VK_ESCAPE:

MessageBox(hWnd,"ESC鍵按下了!","Keyboard",MB_OK);

break;

}

break;

case WM_RBUTTONDOWN://鼠標(biāo)消息

{

MessageBox(hWnd,"鼠標(biāo)右鍵按下了!","Mouse",MB_OK);

break;

}

case WM_PAINT://窗口重畫消息

{

char hello[]="你好,我是EasyWin !";

HDC hdc;

PAINTSTRUCT ps;

hdc=BeginPaint( hWnd,&ps ); //取得設(shè)備環(huán)境句柄

SetTextColor(hdc, RGB(0,0,255)); //設(shè)置文字顏色

TextOut( hdc, 20, 10, hello, strlen(hello) );//輸出文字

EndPaint( hWnd, &ps ); //釋放資源

break;

}

case WM_DESTROY://退出消息

PostQuitMessage( 0 );//調(diào)用退出函數(shù)

break;

}

//調(diào)用缺省消息處理過(guò)程

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

}

  程序輸入完畢,即可編譯執(zhí)行。在窗口中擊鼠標(biāo)鍵或按ESC鍵時(shí),會(huì)彈出一個(gè)對(duì)話框以表示你的操作。

  其實(shí),這個(gè)程序可以看成是所有Win32應(yīng)用程序的框架,在以后所有的程序中,你會(huì)發(fā)現(xiàn)它們都是在這個(gè)程序的基礎(chǔ)之上再添加代碼。


  WinMain()函數(shù)
 
  WinMain()函數(shù)是應(yīng)用程序開(kāi)始執(zhí)行時(shí)的入口點(diǎn),通常也是應(yīng)用程序結(jié)束任務(wù)退出時(shí)的出口點(diǎn)。它與DOS程序的main()函數(shù)起同樣的作用,有一點(diǎn)不同的是,WinMain()函數(shù)必須帶有四個(gè)參數(shù),它們是系統(tǒng)傳遞給它的。WinMain()函數(shù)的原型如下:

int PASCAL WinMain( HINSTANCE hInstance, //當(dāng)前實(shí)例句柄

HINSTANCE hPrevInstance, //前一個(gè)實(shí)例句柄

LPSTR lpCmdLine, //命令行字符

int nCmdShow) //窗口顯示方式

  第一個(gè)參數(shù)hInstance,是標(biāo)識(shí)該應(yīng)用程序當(dāng)前的實(shí)例的句柄。它是HINSTANCE類型,HINSTANCE是Handle of Instance的縮寫,表示實(shí)例的句柄。hInstance是一個(gè)很關(guān)鍵的數(shù)據(jù),它唯一的代表該應(yīng)用程序,在后面初始化程序主窗口的過(guò)程中需要用到這個(gè)參數(shù)。

  這里有兩個(gè)概念,一個(gè)是實(shí)例,一個(gè)是句柄。實(shí)例代表的是應(yīng)用程序執(zhí)行的整個(gè)過(guò)程和方法,一個(gè)應(yīng)用程序如果沒(méi)有被執(zhí)行,只是存在于磁盤上,那么就說(shuō)它是沒(méi)有被實(shí)例化的;只要一執(zhí)行,則說(shuō)該程序的一個(gè)實(shí)例在運(yùn)行。句柄,顧名思義,指的是一個(gè)對(duì)象的把柄。在Windows中,有各種各樣的句柄,它們都是32位的指針變量,用來(lái)指向該對(duì)象所占據(jù)的內(nèi)存區(qū)。句柄的使用,可以極大的方便Windows管理其內(nèi)存中的各種對(duì)象。

  第二個(gè)參數(shù)是hPrevInstance,它是用來(lái)標(biāo)識(shí)該應(yīng)用程序的前一個(gè)實(shí)例句柄。對(duì)于基于Win32的應(yīng)用程序來(lái)說(shuō),這個(gè)參數(shù)總是NULL。這是因?yàn)樵赪in95操作系統(tǒng)中,應(yīng)用程序的每個(gè)實(shí)例都有各自獨(dú)立的地址空間,即使同一個(gè)應(yīng)用程序被執(zhí)行了兩次,在內(nèi)存中也會(huì)為它們的每一個(gè)實(shí)例分配新的內(nèi)存空間,所以一個(gè)應(yīng)用程序被執(zhí)行后,不會(huì)有前一個(gè)實(shí)例存在的可能。也就是說(shuō),hPrevInstance這個(gè)參數(shù)是完全沒(méi)有必要的,只是為了提供與16位Windows的應(yīng)用程序形式上的兼容性,才保留了這個(gè)參數(shù)。在以前的16位Windows環(huán)境下(如Windows3.2),hPrevInstance用來(lái)標(biāo)識(shí)與hInstance相關(guān)的應(yīng)用程序的前一個(gè)句柄。

  第三個(gè)參數(shù)是lpCmdLine,是指向應(yīng)用程序命令行參數(shù)字符串的指針。如在Win95的“開(kāi)始”菜單中單擊“運(yùn)行”,輸入“easywin hello”,則此參數(shù)指向的字符串為“hello”。

  最后一個(gè)參數(shù)是nCmdShow,是一個(gè)用來(lái)指定窗口顯示方式的整數(shù)。這個(gè)整數(shù)值可以是SW_SHOW、SW_HIDE、SW_SHOWMAXIMIZED、SW_SHOWMINIMIZED等,關(guān)于這些值的含義,將在下一節(jié)說(shuō)明。


  注冊(cè)窗口類

  一個(gè)應(yīng)用程序可以有許多窗口,但只有一個(gè)是主窗口,它是與該應(yīng)用程序的實(shí)例句柄唯一關(guān)聯(lián)的。上面的例程中,創(chuàng)建主窗口的函數(shù)是InitWindow()。

  通常要對(duì)填充一個(gè)窗口類結(jié)構(gòu)WNDCLASS,然后調(diào)用RegisterClass()對(duì)該窗口類進(jìn)行注冊(cè)。每個(gè)窗口都有一些基本的屬性,如窗口邊框、窗口標(biāo)題欄文字、窗口大小和位置、鼠標(biāo)、背景色、處理窗口消息函數(shù)的名稱等等。注冊(cè)的過(guò)程也就是將這些屬性告訴系統(tǒng),然后再調(diào)用CreateWindow()函數(shù)創(chuàng)建出窗口。這也就象你去裁縫店訂做一件衣服,先要告訴店老板你的身材尺寸、布料顏色、以及你想要的款式,然后他才能為你做出一件讓你滿意的衣服。

  在VC的幫助中,可以看到WNDCLASS結(jié)構(gòu)是這樣定義的:

typedef struct _WNDCLASS {

UINT style; //窗口的風(fēng)格*

WNDPROC lpfnWndProc; //指定窗口的消息處理函數(shù)的遠(yuǎn)指針*

int cbClsExtra; //指定分配給窗口類結(jié)構(gòu)之后的額外字節(jié)數(shù)*

int cbWndExtra; //指定分配給窗口實(shí)例之后的額外字節(jié)數(shù)

HANDLE hInstance; //指定窗口過(guò)程所對(duì)應(yīng)的實(shí)例句柄*

HICON hIcon; //指定窗口的圖標(biāo)

HCURSOR hCursor; //指定窗口的鼠標(biāo)

HBRUSH hbrBackground; //指定窗口的背景畫刷

LPCTSTR lpszMenuName; //窗口的菜單資源名稱

LPCTSTR lpszClassName; //該窗口類的名稱*

} WNDCLASS;

  在Win95和WinNT的具有新界面特性的系統(tǒng)中,為了支持新的窗口界面特性,還有一種擴(kuò)展的窗口類型WNDCLASSEX,它的定義如下:

typedef struct _WNDCLASSEX {

UINT cbSize; //指定WNDCLASSEX結(jié)構(gòu)的大小

UINT style;

WNDPROC lpfnWndProc;

int cbClsExtra;

int cbWndExtra;

HANDLE hInstance;

HICON hIcon;

HCURSOR hCursor;

HBRUSH hbrBackground;

LPCTSTR lpszMenuName;

LPCTSTR lpszClassName;

HICON hIconSm; //窗口的小圖標(biāo)

} WNDCLASSEX;

  WNDCLASS和WNDCLASSEX這兩個(gè)結(jié)構(gòu)基本上是一致的,只是WNDCLASSEX結(jié)構(gòu)中多了cbSize和hIconSm這兩個(gè)成員。WNDCLASS結(jié)構(gòu)的各成員中,其注釋后打了星號(hào)的表示該項(xiàng)應(yīng)特別注意。

  WNDCLASS結(jié)構(gòu)的第一個(gè)成員style表示窗口類的風(fēng)格,它往往是由一些基本的風(fēng)格通過(guò)位的“或”操作(操作符位“|”)組合而成。下表列出了一些常用的基本窗口風(fēng)格:

風(fēng)格 含義
CS_HREDRAW 如果窗口客戶區(qū)寬度發(fā)生改變,重繪整個(gè)窗口
CS_VREDRAW 如果窗口客戶區(qū)高度發(fā)生改變,重繪整個(gè)窗口
CS_DBLCLKS 能感受用戶在窗口中的雙擊消息
CS_NOCLOSE 禁用系統(tǒng)菜單中的“關(guān)閉”命令
CS_OWNDC 為該窗口類的各窗口分配各自獨(dú)立的設(shè)備環(huán)境
CS_CLASSDC 為該窗口類的各窗口分配一個(gè)共享的設(shè)備環(huán)境
CS_PARENTDC 指定子窗口繼承其父窗口的設(shè)備環(huán)境
CS_SAVEBITS 把被窗口遮掩的屏幕圖象部分作為位圖保存起來(lái)。當(dāng)該窗口被移動(dòng)時(shí),Windows使用被保存的位圖來(lái)重建屏幕圖象

  在EasyWin應(yīng)用程序中,是按如下方式對(duì)WNDCLASS結(jié)構(gòu)進(jìn)行填充和注冊(cè)的:

wc.style = CS_VREDRAW | CS_HREDRAW;

wc.lpfnWndProc = (WNDPROC)WinProc;

wc.cbClsExtra = 0;

wc.cbWndExtra = 0;

wc.hInstance = hInstance;

wc.hIcon = LoadIcon( hInstance, IDI_APPLICATION );

wc.hCursor = LoadCursor( NULL, IDC_ARROW );

wc.hbrBackground = GetStockObject(WHITE_BRUSH);

wc.lpszMenuName = NULL;

wc.lpszClassName = "EasyWin";

  可以看到,wc.style被設(shè)為CS_VREDRAW | CS_HREDRAW,表示只要窗口的高度或?qū)挾劝l(fā)生變化,都會(huì)重畫整個(gè)窗口。

  第二個(gè)成員lpfnWndProc的值為(WNDPROC)WinProc。表明該窗口類的消息處理函數(shù)是WinProc()函數(shù)。這里,要指定窗口的消息處理函數(shù)的遠(yuǎn)指針,輸入消息處理函數(shù)的函數(shù)名稱即可,必要時(shí)應(yīng)該進(jìn)行強(qiáng)制類型轉(zhuǎn)換,將其轉(zhuǎn)換成WNDPROC型。

  接下來(lái)的cbClsExtra和wc.cbWndExtra在大多數(shù)情況下都會(huì)設(shè)為0。

  然后的hInstance成員,給它的值是由WinMain()傳來(lái)的應(yīng)用程序的實(shí)例句柄,表明該窗口與該實(shí)例是相關(guān)聯(lián)的。事實(shí)上,只要是注冊(cè)窗口類,該成員的值始終是該程序的實(shí)例句柄,你應(yīng)該象背書一樣記住它。

  下面的hIcon,是讓你給這個(gè)窗口指定一個(gè)圖標(biāo),調(diào)用 LoadIcon( hInstance, IDI_APPLICATION ),可以調(diào)用系統(tǒng)內(nèi)部預(yù)先定義好的標(biāo)志符為IDC_APPLICATION的圖標(biāo)作為該窗口的圖標(biāo)。

  同樣,調(diào)用LoadCursor( NULL, IDC_ARROW )為該窗口調(diào)用系統(tǒng)內(nèi)部預(yù)先定義好的箭頭型鼠標(biāo)。

  hbrBackground成員用來(lái)定義窗口的背景畫刷顏色,也就是該窗口的背景色。調(diào)用GetStockObject(WHITE_BRUSH)可以獲得系統(tǒng)內(nèi)部預(yù)先定義好的白色畫刷作為窗口的背景色。

  上面的LoadIcon()、LoadCursor()、GetStockObject()都是Windows的API函數(shù),它們的用法可以參看VC的幫助,這里就不多介紹了。

  lpszMenuName成員的值我們給它NULL,表示該窗口將沒(méi)有菜單。如果你想讓你的窗口擁有菜單,就把lpszMenuName成員賦值為標(biāo)志菜單資源的字符串。

  WNDCLASS結(jié)構(gòu)的最后一個(gè)成員lpszClassName是讓你給這個(gè)窗口類起一個(gè)唯一的名稱,因?yàn)閃indows操作系統(tǒng)中有許許多多的窗口類,必須用一個(gè)獨(dú)一無(wú)二的名稱來(lái)代表它們。通常,你可以用你的程序名來(lái)命名這個(gè)窗口類的名稱。這個(gè)名稱將在創(chuàng)建窗口的CreateWindow()函數(shù)中用到。

  填充完畢后,對(duì)于WNDCLASS結(jié)構(gòu),調(diào)用RegisterClass()函數(shù)進(jìn)行注冊(cè);對(duì)于WNDCLASSEX結(jié)構(gòu),調(diào)用RegisterClassEx()函數(shù)進(jìn)行注冊(cè),它們的原型分別如下:

ATOM RegisterClass( CONST WNDCLASS *lpWndClass );

ATOM RegisterClassEx( CONST WNDCLASSEX *lpwcx );

  該函數(shù)如調(diào)用成功,則返回一個(gè)非0值,表明系統(tǒng)中已經(jīng)注冊(cè)了一個(gè)名為EasyWin的窗口類。如果失敗,則返回0。


  創(chuàng)建窗口

  當(dāng)窗口類注冊(cè)完畢之后,并不會(huì)有窗口顯示出來(lái),因?yàn)樽?cè)的過(guò)程僅僅是為創(chuàng)建窗口所做的準(zhǔn)備工作。實(shí)際創(chuàng)建一個(gè)窗口的是通過(guò)調(diào)用CreateWindow()函數(shù)完成的。窗口類中已經(jīng)預(yù)先定義了窗口的一般屬性,而CreateWindow()中的參數(shù)可以進(jìn)一步指定一個(gè)窗口的更具體的屬性,在EasyWin程序中,是如下調(diào)用CreateWindow()函數(shù)來(lái)創(chuàng)建窗口的:

hwnd = CreateWindow(

"EasyWin", //創(chuàng)建窗口所用的窗口類的名稱*

"一個(gè)基本的Win32程序", //窗口標(biāo)題

WS_OVERLAPPEDWINDOW, //窗口風(fēng)格,定義為普通型*

100, //窗口位置的x坐標(biāo)

100, //窗口位置的y坐標(biāo)

400, //窗口的寬度

300, //窗口的高度

NULL, //父窗口句柄

NULL, //菜單句柄

hInstance, //應(yīng)用程序實(shí)例句柄*

NULL ); //一般都為NULL

  CreateWindow()函數(shù)的參數(shù)的含義在上面的注釋中已有介紹,注釋后打了星號(hào)標(biāo)記的參數(shù)應(yīng)該著重注意,其它的參數(shù)都很簡(jiǎn)單,不多做介紹,可參看VC的幫助。

  第一個(gè)參數(shù)是創(chuàng)建該窗口所使用的窗口類的名稱,注意這個(gè)名稱應(yīng)與前面所注冊(cè)的窗口類的名稱一致。

  第三個(gè)參數(shù)為創(chuàng)建的窗口的風(fēng)格,下表列出了常用的窗口風(fēng)格:

風(fēng)格 含義
WS_OVERLAPPEDWINDOW 創(chuàng)建一個(gè)層疊式窗口,有邊框、標(biāo)題欄、系統(tǒng)菜單、最大最小化按鈕,是以下幾種風(fēng)格的集合:WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU, WS_THICKFRAME, WS_MINIMIZEBOX, WS_MAXIMIZEBOX
WS_POPUPWINDOW 創(chuàng)建一個(gè)彈出式窗口,是以下幾種風(fēng)格的集合: WS_BORDER,WS_POPUP,WS_SYSMENU。WS_CAPTION與WS_POPUPWINDOW風(fēng)格必須一起使用才能使窗口菜單可見(jiàn)
WS_OVERLAPPED 創(chuàng)建一個(gè)層疊式窗口,它有標(biāo)題欄和邊框,與WS_TILED風(fēng)格一樣
WS_POPUP 該窗口為彈出式窗口,不能與WS_CHILD同時(shí)使用
WS_BORDER 窗口有單線邊框
WS_CAPTION 窗口有標(biāo)題欄
WS_CHILD 該窗口為子窗口,不能與WS_POPUP同時(shí)使用
WS_DISABLED 該窗口為無(wú)效,即對(duì)用戶操作不產(chǎn)生任何反應(yīng)
WS_HSCROLL 窗口有水平滾動(dòng)條
WS_ICONIC 窗口初始化為最小化
WS_MAXIMIZE 窗口初始化為最大化
WS_MAXIMIZEBOX 窗口有最大化按鈕
WS_MINIMIZE 與WS_MAXIMIZE一樣
WS_MINIMIZEBOX 窗口有最小化按鈕
WS_SIZEBOX 邊框可進(jìn)行大小控制的窗口
WS_SYSMENU 創(chuàng)建一個(gè)有系統(tǒng)菜單的窗口,必須與WS_CAPTION風(fēng)格同時(shí)使用
WS_THICKFRAME 創(chuàng)建一個(gè)大小可控制的窗口,與WS_SIZEBOX 風(fēng)格一樣.
WS_TILED 創(chuàng)建一個(gè)層疊式窗口,有標(biāo)題欄
WS_VISIBLE 窗口為可見(jiàn)
WS_VSCROLL 窗口有垂直滾動(dòng)條

  程序中使用了WS_OVERLAPPEDWINDOW標(biāo)志,它是創(chuàng)建一個(gè)普通窗口常用的標(biāo)志。而在DirectX編程中,我們常用的是WS_POPUP,用這個(gè)標(biāo)志創(chuàng)建的窗口沒(méi)有標(biāo)題欄和系統(tǒng)菜單,如果設(shè)定窗口為最大化,客戶區(qū)可以占滿整個(gè)屏幕,以滿足DirectX編程的需要。

  CreateWindow()函數(shù)后面的參數(shù)中,仍用到了該應(yīng)用程序的實(shí)例句柄hInstance。

  如果窗口創(chuàng)建成功,返回值是新窗口的句柄,否則返回NULL。


  顯示和更新窗口

  窗口創(chuàng)建后,并不會(huì)在屏幕上顯示出來(lái),要真正把窗口顯示在屏幕上,還得使用ShowWindow()函數(shù),其原型如下:

BOOL ShowWindow( HWND hWnd, int nCmdShow );

  參數(shù)hWnd指定要顯示得窗口的句柄,nCmdShow表示窗口的顯示方式,這里指定為從WinMain()函數(shù)的nCmdShow所傳遞而來(lái)的值。

  由于ShowWindow()函數(shù)的執(zhí)行優(yōu)先級(jí)不高,所以當(dāng)系統(tǒng)正忙著執(zhí)行其它的任務(wù)時(shí),窗口不會(huì)立即顯示出來(lái),此時(shí),調(diào)用UpdateWindow()函數(shù)以可以立即顯示窗口。其函數(shù)原型如下:

BOOL UpdateWindow( HWND hWnd );

  消息循環(huán)

  在Win32編程中,消息循環(huán)是相當(dāng)重要的一個(gè)概念,看似很難,但是使用起來(lái)卻是非常簡(jiǎn)單。在WinMain()函數(shù)中,調(diào)用InitWindow()函數(shù)成功的創(chuàng)建了應(yīng)用程序主窗口之后,就要啟動(dòng)消息循環(huán),其代碼如下:

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

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

  Windows應(yīng)用程序可以接收以各種形式輸入的信息,這包括鍵盤、鼠標(biāo)動(dòng)作 、記時(shí)器產(chǎn)生的消息,也可以是其它應(yīng)用程序發(fā)來(lái)的消息等等。Windows系統(tǒng)自動(dòng)監(jiān)控所有的輸入設(shè)備,并將其消息放入該應(yīng)用程序的消息隊(duì)列中。

  GetMessage()函數(shù)則是用來(lái)從應(yīng)用程序的消息隊(duì)列中按照先進(jìn)先出的原則將這些消息一個(gè)個(gè)的取出來(lái),放進(jìn)一個(gè)MSG結(jié)構(gòu)中去。GetMessage()函數(shù)原型如下:

BOOL GetMessage(

LPMSG lpMsg, //指向一個(gè)MSG結(jié)構(gòu)的指針,用來(lái)保存消息

HWND hWnd, //指定哪個(gè)窗口的消息將被獲取

UINT wMsgFilterMin, //指定獲取的主消息值的最小值

UINT wMsgFilterMax //指定獲取的主消息值的最大值

);

  GetMessage()將獲取的消息復(fù)制到一個(gè)MSG結(jié)構(gòu)中。如果隊(duì)列中沒(méi)有任何消息,GetMessage()函數(shù)將一直空閑直到隊(duì)列中又有消息時(shí)再返回。如果隊(duì)列中已有消息,它將取出一個(gè)后返回。MSG結(jié)構(gòu)包含了一條Windows消息的完整信息,其定義如下:

typedef struct tagMSG {

HWND hwnd; //接收消息的窗口句柄

UINT message; //主消息值

WPARAM wParam; //副消息值,其具體含義依賴于主消息值

LPARAM lParam; //副消息值,其具體含義依賴于主消息值

DWORD time; //消息被投遞的時(shí)間

POINT pt; //鼠標(biāo)的位置

} MSG;

  該結(jié)構(gòu)中的主消息表明了消息的類型,例如是鍵盤消息還是鼠標(biāo)消息等,副消息的含義則依賴于主消息值,例如:如果主消息是鍵盤消息,那么副消息中則存儲(chǔ)了是鍵盤的哪個(gè)具體鍵的信息。

  GetMessage()函數(shù)還可以過(guò)濾消息,它的第二個(gè)參數(shù)是用來(lái)指定從哪個(gè)窗口的消息隊(duì)列中獲取消息,其它窗口的消息將被過(guò)濾掉。如果該參數(shù)為NULL,則GetMessage()從該應(yīng)用程序線程的所有窗口的消息隊(duì)列中獲取消息。

  第三個(gè)和第四個(gè)參數(shù)是用來(lái)過(guò)濾MSG結(jié)構(gòu)中主消息值的,主消息值在wMsgFilterMin和wMsgFilterMax之外的消息將被過(guò)濾掉。如果這兩個(gè)參數(shù)為0,則表示接收所有消息。

  當(dāng)且僅當(dāng)GetMessage()函數(shù)在獲取到WM_QUIT消息后,將返回0值,于是程序退出消息循環(huán)。

  TranslateMessage()函數(shù)的作用是把虛擬鍵消息轉(zhuǎn)換到字符消息,以滿足鍵盤輸入的需要。DispatchMessage()函數(shù)所完成的工作是把當(dāng)前的消息發(fā)送到對(duì)應(yīng)的窗口過(guò)程中去。

  開(kāi)啟消息循環(huán)其實(shí)是很簡(jiǎn)單的一個(gè)步驟,幾乎所有的程序都是按照EasyWin的這個(gè)方法。你完全不必去深究這些函數(shù)的作用,只是簡(jiǎn)單的照抄就可以了。
 

  消息處理函數(shù)

  消息處理函數(shù)又叫窗口過(guò)程,在這個(gè)函數(shù)中,不同的消息將用switch語(yǔ)句分配到不同的處理程序中去。Windows的消息處理函數(shù)都有一個(gè)確定的樣式,即這種函數(shù)的參數(shù)個(gè)數(shù)和類型以及其返回值的類型都有明確的規(guī)定。在VC的說(shuō)明書中,消息處理函數(shù)的原型是這樣定義的:

LRESULT CALLBACK WindowProc(

HWND hwnd, //接收消息窗口的句柄

UINT uMsg, //主消息值

WPARAM wParam, //副消息值

LPARAM lParam //副消息值

);

  如果你的程序中還有其它的消息處理函數(shù),也都必須按照上面的這個(gè)樣式來(lái)定義,但函數(shù)名稱可以隨便取。EasyWin中的WinProc()函數(shù)就是這樣一個(gè)典型的消息處理函數(shù)。

  消息處理函數(shù)的四個(gè)參數(shù)是由GetMessage()函數(shù)從消息隊(duì)列中獲得MSG結(jié)構(gòu),然后分解后得到的。第二個(gè)參數(shù)uMsg和MSG結(jié)構(gòu)中的message值是一致的,代表了主消息值。程序中用switch語(yǔ)句來(lái)將不同類型的消息分配到不同的處理程序中去。

  WinProc()函數(shù)明確的處理了4個(gè)消息,分別是WM_KEYDOWN(擊鍵消息)、WM_RBUTTONDOWN(鼠標(biāo)右鍵按下消息)、WM_PAINT(窗口重畫消息)、WM_DESTROY(銷毀窗口消息)。

  值得注意的是,應(yīng)用程序發(fā)送到窗口的消息遠(yuǎn)遠(yuǎn)不止以上這幾條,象WM_SIZE、WM_MINIMIZE、WM_CREATE、WM_MOVE等這樣頻頻使用的消息就有幾十條。為了減輕編程的負(fù)擔(dān),Windows的API提供了DefWindowProc()函數(shù)來(lái)處理這些最常用的消息,調(diào)用了這個(gè)函數(shù)后,這些消息將按照系統(tǒng)默認(rèn)的方式得到處理。

  因此,在switch_case語(yǔ)句中,只須明確的處理那些有必要進(jìn)行特別響應(yīng)的消息,把其余的消息交給DefWindowProc()函數(shù)來(lái)處理,是一種明智的選擇,也是你必須做的一件事。
 
  結(jié)束消息循環(huán)

  當(dāng)用戶按Alt+F4或單擊窗口右上角的退出按鈕,系統(tǒng)就向應(yīng)用程序發(fā)送一條WM_DESTROY的消息。在處理此消息時(shí),調(diào)用了PostQuitMessage()函數(shù),該函數(shù)會(huì)給窗口的消息隊(duì)列中發(fā)送一條WM_QUIT的消息。在消息循環(huán)中,GetMessage()函數(shù)一旦檢索到這條消息,就會(huì)返回FALSE,從而結(jié)束消息循環(huán),隨后,程序也結(jié)束。

  小結(jié)

  本章介紹的是Win32編程的基礎(chǔ)知識(shí),在進(jìn)行DirectX編程之前,掌握它們是十分必要的。

  通過(guò)本文的學(xué)習(xí),你應(yīng)該學(xué)到以下知識(shí):

   如何創(chuàng)建一個(gè)Win32應(yīng)用程序工程

   用RegisterClass()函數(shù)注冊(cè)一個(gè)窗口類,再立即調(diào)用CreateWindow()函數(shù)創(chuàng)建一個(gè)窗口的實(shí)例

   設(shè)置窗口的類型以及將一個(gè)消息處理函數(shù)與窗口聯(lián)系上

   用一固定的模式開(kāi)啟消息循環(huán)

   了解消息處理函數(shù)的定義規(guī)則,如何自己定義一個(gè)窗口消息處理函數(shù)

   在消息處理函數(shù)中,最后必須調(diào)用DefWindowProc()函數(shù)以處理那些缺省的消息

   調(diào)用PostQuitMessage()函數(shù)以結(jié)束消息循環(huán)

Posted on 2005-11-11 13:44 艾凡赫 閱讀(347) 評(píng)論(0)  編輯 收藏 引用 所屬分類: MFC技術(shù)
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            激情久久五月| 国产美女精品| 久久综合久久久久88| 亚洲视频在线二区| 欧美大片免费看| 午夜精品成人在线视频| 欧美日韩亚洲综合| 亚洲精品久久久久久久久久久久 | 欧美三级第一页| 亚洲精品美女在线观看播放| 久久婷婷蜜乳一本欲蜜臀| 制服诱惑一区二区| 国产精品久久久久久久久久尿| 樱桃成人精品视频在线播放| 久久久久久久久久久一区 | 欧美日韩精品欧美日韩精品一| 亚洲第一福利社区| 免费欧美视频| 久久免费视频网站| 亚洲国产1区| 亚洲激情自拍| 欧美人妖另类| 亚洲自拍另类| 亚洲欧美成人一区二区三区| 欧美午夜免费影院| 亚洲欧美另类在线| 亚洲午夜激情免费视频| 女人天堂亚洲aⅴ在线观看| 午夜久久tv| 尹人成人综合网| 欧美v日韩v国产v| 美国十次成人| 亚洲人成在线免费观看| 亚洲第一黄色| 欧美视频在线观看免费| 一本色道88久久加勒比精品| 久久久久久久一区二区三区| 中文成人激情娱乐网| 亚洲福利视频一区| 一本色道久久综合亚洲精品按摩 | 国产欧美日韩不卡| 另类人畜视频在线| 亚洲五月六月| 欧美99久久| 国产欧美日韩在线视频| 一本色道**综合亚洲精品蜜桃冫| 亚洲狠狠婷婷| 亚洲主播在线观看| 亚洲国产美女精品久久久久∴| 一本色道久久加勒比精品 | 欧美aaa级| 国产精品丝袜xxxxxxx| 牛牛影视久久网| 欧美极品在线观看| 亚洲国产三级在线| 欧美日韩dvd在线观看| 欧美喷水视频| 亚洲电影免费观看高清| 亚洲国产清纯| 亚洲在线视频观看| 亚洲一区二区成人在线观看| 夜夜嗨av一区二区三区四季av| 日韩午夜在线| 免费影视亚洲| 欧美一区在线视频| 欧美日韩岛国| 日韩亚洲一区二区| 亚洲国产aⅴ天堂久久| 久久精品免费观看| 在线电影一区| 美日韩在线观看| 久久精品国产在热久久| 伊人久久婷婷色综合98网| 亚洲国产网站| 欧美在线观看视频一区二区| 国内精品视频一区| 久久综合激情| 亚洲欧美日韩在线播放| 日韩视频在线免费观看| 欧美激情第1页| 亚洲视频1区| 久久精品视频在线观看| 国产日韩1区| 久久免费的精品国产v∧| 久久精品一区二区三区不卡牛牛| 好看的av在线不卡观看| 美日韩丰满少妇在线观看| 男女激情久久| 亚洲一级在线观看| 久久综合久久综合久久| 国产欧美在线观看| 免费欧美在线| 欧美日韩国产综合视频在线| 亚洲区欧美区| 亚洲欧美日韩中文在线制服| 国内精品一区二区三区| 久久高清福利视频| 国产精品专区第二| 欧美一区在线看| 激情婷婷亚洲| 午夜精品区一区二区三| 欧美亚洲综合网| 免费一级欧美片在线播放| 欧美激情一区二区三区全黄| 欧美三级在线视频| 久久亚洲综合色一区二区三区| 欧美激情性爽国产精品17p| 午夜视频久久久久久| 亚洲国产一区二区三区a毛片| 黄色成人小视频| 99在线精品免费视频九九视| 一区二区三区四区五区精品| 国产精品视频久久久| 一本久久综合| 国产视频欧美| 亚洲一区观看| 中文成人激情娱乐网| 国产精品亚洲а∨天堂免在线| 久久精品一级爱片| 亚洲日本国产| 久久精品一区二区三区不卡| 美女精品一区| 亚洲人成小说网站色在线| 久久成人综合视频| 国产精品美女久久| 亚洲日本黄色| 亚洲欧洲精品一区二区三区波多野1战4 | 亚洲日本欧美日韩高观看| 日韩午夜电影av| 国产综合久久久久久| 91久久精品一区二区别| 精品91视频| 亚洲一级二级在线| 日韩西西人体444www| 久久夜色精品国产亚洲aⅴ| 亚洲国产另类久久久精品极度| 国产模特精品视频久久久久| 在线中文字幕一区| 亚洲三级国产| 久久午夜视频| 久久精品五月| 国产精品久久精品日日| 国模精品一区二区三区色天香| 美女在线一区二区| 老巨人导航500精品| 国产在线不卡精品| 性色一区二区| 欧美一级一区| 亚洲欧美在线网| 国产精品v欧美精品∨日韩| 亚洲精品日韩激情在线电影| 亚洲人成7777| 欧美国产日韩一区二区| 久久精品视频99| 久久夜色精品国产| 一区在线观看视频| 老司机免费视频一区二区三区| 日韩视频一区二区三区| 欧美成人国产一区二区| 欧美中文日韩| 亚洲精品欧美专区| 一区二区av在线| 欧美日韩一级黄| 一本不卡影院| 欧美激情精品久久久久久大尺度| 美女日韩欧美| 久久综合给合| 亚洲国产高潮在线观看| 日韩亚洲欧美中文三级| 欧美日韩理论| 亚洲欧美日韩精品久久亚洲区 | 亚洲欧洲一区| 国产女人水真多18毛片18精品视频| 欧美性开放视频| 国产综合久久| 亚洲精品日韩在线观看| 亚洲综合国产激情另类一区| av不卡在线观看| 美女精品一区| 国语精品中文字幕| 亚洲天堂av在线免费| 久久成人免费| 校园春色综合网| 亚洲国产婷婷香蕉久久久久久99| 国产亚洲人成a一在线v站 | 亚洲国产精品一区制服丝袜| 久久天堂国产精品| 99综合视频| 国产精品亚洲成人| 日韩西西人体444www| 亚洲肉体裸体xxxx137| 一区二区三区精密机械公司 | 韩国精品久久久999| 免费亚洲一区二区| 亚洲激情影院| 欧美日韩hd| 欧美一级电影久久| 香蕉久久久久久久av网站| 免费短视频成人日韩| 亚洲一区二区三区免费视频|