天天看點

<Win32_1>深入淺出windows消息機制

本文由BlueCoder編寫   轉載請說明出處:

http://blog.csdn.net/crocodile__/article/details/9417439

我的郵箱:[email protected]    歡迎大家和我交流程式設計心得

我的微網誌:BlueCoder_黎小華    歡迎光臨^_^

上學期學習了Java ,感覺Java寫一個視窗真心簡單,很易上手,也就難怪很多開發人員選擇Java作為自己的開發程式設計語言。但是由于自身對windows的熱愛,讓我覺得c、c++語言才是我親睐的程式設計語言,雖然難度大些,但是這才能展現能力所在。其實之前一直想自學一下win32,但是由于時間的顯示和種種原因而耽擱了,于是今年暑假決心深入學習win32。

在學習過程中呢,我會在此留下自己的學習心得,當做自己的筆記。初學者可以借鑒,高手可以多多指教,呵呵……

好了,今天開始做第一課的筆記吧:

學習Win32最好是對windows作業系統有較為深入的了解,這樣才能學得深入、紮實。是以學習Win32的第一步就是了解windows

作業系統的消息機制,這個可是重中之重

首先上一張自己親手繪制的圖,能很清晰地表示windows消息機制的工作原理

<Win32_1>深入淺出windows消息機制

也許你初次看到這張圖,感覺密密麻麻的,不是很懂,别擔心,我将逐漸講解:

(1)   數字1箭頭:  表示windows(os)将消息傳遞到應用程式的消息隊列中

(2)   數字2箭頭:  表示應用程式通過消息循環在消息隊列中讀取消息

(3)   數字3箭頭:  表示應用程式的消息循環将讀取到的消息告訴給windows(os)

(4)   數字4箭頭:  表示windows(os)通過應用程式傳遞的消息來調用應用程式綁定的回調函數(WndProc) , 根據回調函數 , 來确定是否做出響應

到這裡,想必你能從本質上了解到windows的消息機制了吧

講程式終究和代碼脫不了關系,下面我借用一下P先生(Charles Petzold)的第一個例子(HelloWin.c),不過裡面包含了我自己的東西,你一看就知道了:

//windows程式的基礎代碼
#include<windows.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);//回調函數聲明

int WINAPI WinMain(HINSTANCE hInstance,		// 程式的目前執行個體句柄
				   HINSTANCE hPrevInstance, // 程式的上一個執行個體句柄 , 在win32程式中 , 它始終是NULL
                   PSTR szCmdLine,			// 指令行
				   int iCmdShow)			// 視窗顯示狀态
{
	static	TCHAR	szAppName[] = TEXT("HelloWin");	//以'\0'字元結尾的字元串 , 這裡是程式的名稱(實際用作後面的視窗類的名字)
	HWND			hwnd;							//視窗句柄
	MSG				msg;							//消息結構體
	WNDCLASS		wndclass;						//視窗類
	
	wndclass.style			= CS_HREDRAW | CS_VREDRAW;				//視窗類的風格
	wndclass.lpfnWndProc	= WndProc;								//視窗類綁定的回調函數(也稱為視窗過程)
	wndclass.cbClsExtra		= 0;									//視窗類額外參數(預設為0)
	wndclass.cbWndExtra		= 0;//視窗類額外參數(預設為0)	
	wndclass.hInstance		= hInstance;							//程式的目前執行個體句柄 , 綁定到視窗類中
	wndclass.hIcon			= LoadIcon(NULL, IDI_APPLICATION);		//加載程式圖示
	wndclass.hCursor		= LoadCursor(NULL, IDC_ARROW);			//加載光标
	wndclass.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH);	//背景刷
	wndclass.lpszMenuName	= NULL;									//菜單名指針
	wndclass.lpszClassName	= szAppName;							//視窗類的名字
	
	if(!RegisterClass(&wndclass))//注冊視窗類
	{
		MessageBox(NULL, TEXT("This program requires Windows NT!"),
			szAppName, MB_ICONERROR);
		return 0;
	}
	
	//這裡建立的是一段記憶體 , 用于存儲建立視窗的資訊 , 同時傳回該視窗的一個句柄(視窗的标示)
	hwnd = CreateWindow(szAppName,					//視窗類的名字
						TEXT("The Hello Program"),	//視窗名稱(标題欄顯示的内容)
						WS_OVERLAPPEDWINDOW,		//視窗的風格
						CW_USEDEFAULT,				//視窗x坐标
						CW_USEDEFAULT,				//視窗y坐标
						CW_USEDEFAULT,				//視窗寬度
						CW_USEDEFAULT,				//視窗長度
						NULL,						//父視窗句柄
						NULL,						//菜單句柄
						hInstance,					//程式的目前執行個體
						NULL);						//視窗建立資料

	/* 程式運作完CreateWindow , 還沒運作ShowWindow時 , 
	windows向視窗的WndProc發送了第一條消息: WM_Create */

	ShowWindow(hwnd, iCmdShow);	//顯示視窗
	UpdateWindow(hwnd);			//更新視窗
	/* 運作完UpdateWindow後 , windows向視窗的WndProc
	發送了第二條消息: WM_PAINT . 如果ShowWindow沒有調用或是調用失敗 , WM_PAINT消息是不會發送的*/
	
	//消息循環
	while(GetMessage(&msg, NULL, 0, 0))//這裡的NULL不能寫成hwnd , 否則程式不能正常運作
	{
		TranslateMessage(&msg);//轉換鍵盤消息
		DispatchMessage(&msg);//将消息傳送給windows(os) , 由windows來回調
	}
	
	return msg.wParam;//結束傳回
}

//視窗過程(回調函數)
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	HDC			hdc;	//裝置句柄
	PAINTSTRUCT	ps;		//包含視窗客戶區繪制的資訊  是一個結構體
	RECT		rect;	//矩形(兩個點)
	
	//這裡是消息處理
	switch(message)
	{
	//視窗建立消息
	case WM_CREATE:
	  //PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ;//播音
	  return 0 ;

	//視窗客戶區重繪消息
	case WM_PAINT:
		PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ;//播音
		hdc = BeginPaint(hwnd, &ps);//擷取裝置句柄 , 開始重繪
		
		GetClientRect(hwnd, &rect);//擷取客戶區的大小
		
		DrawText(hdc, TEXT("Hello, Windows 98!"), -1, &rect,
				 DT_SINGLELINE | DT_CENTER | DT_VCENTER);//繪制一個字元串

		EndPaint(hwnd, &ps);//結束重繪
		return 0;

	//視窗退出消息
	case WM_DESTROY:
		PostQuitMessage(0);//發送退出消息
		return 0;
	}

	return DefWindowProc(hwnd, message, wParam, lParam);
	//windows對于消息的預設處理
	//(注意: 第三個和第四個參數不能傳遞錯誤!!!)
}
           

沒錯,我逐行注釋了,這樣我覺得很好,對于掌握和了解是很有幫助的,ni不放試試……

好了,今天到此為止吧,下次繼續了^_^

繼續閱讀