1. 程式人生 > >WIN32學習——Windows訊息機制(一)

WIN32學習——Windows訊息機制(一)

1、Win32視窗程式採用的是事件驅動方式執行,也就是訊息機制,當系統通知視窗工作時,就是採用訊息的方式派發給視窗,通過呼叫視窗處理函式進行對訊息對處理。

2、訊息MessageBox結構體:

int MessageBox(

HWND hWnd, //父視窗控制代碼

LPCTSTR lpText, //顯示在訊息框中的文字

LPCTSTR lpCaption, //顯示在標題欄中的文字

UINT uType //訊息框中的按鈕、圖示顯示型別

); //返回點選的按鈕ID

3、每一個視窗都有視窗處理函式,例如:

LRESULT CALLBACK WindowProc(

HWND hwnd, //視窗控制代碼

UINT uMsg, //訊息ID

WPARAM wParam, //訊息引數

LPARAM lParam //訊息引數

);

當系統通知視窗時,會呼叫視窗處理函式同時,會將訊息ID和訊息引數傳遞給視窗處理函式,在視窗處理函式中,沒有手動處理的訊息會使用預設的視窗處理函式DefWindowProc()。

4、訊息相關函式:

GetMessage();

TranslateMessage();

DispatchMessage();

5、常見訊息:

WM_DESTROY:視窗被銷燬時的訊息,無訊息引數(wParam、lParam),常用於在視窗被銷燬之前,做相應的善後處理,例如資源、記憶體等

WM_SYSCOMMAND:系統命令訊息,當點選視窗的最大化、最小化、關閉等命令時,收到這個訊息。常用在視窗關閉時,提示使用者處理。

WM_CREATE:在視窗建立成功還未顯示之前,收到這個訊息。常用於初始化視窗的引數、資源等,包括子視窗的建立。

WM_SIZE:在視窗大小發生變化後,會收到這個訊息。常用於視窗大小變化後,調節視窗內各個部分的佈局。其中,該訊息的附加資料:WPARAM表示視窗大小變化的原因,LPARAM表示變化後窗口客戶區大小,通過呼叫LOWORD獲取變化後寬度,HIWORD獲取變化後高度。

WM_QUIT:用於結束訊息迴圈處理。

WM_PAINT:繪圖訊息。

另外還有鍵盤訊息、滑鼠訊息、定時器訊息等,以後研究。

附練習程式碼:

/*
功能:在點選關閉視窗按鈕時,提示是否關閉視窗,YES關閉視窗,NO取消關閉視窗
		WM_SYSCOMMAND:
		WM_CREATE:
		WM_SIZE:
		以上訊息的使用
*/

#include <Windows.h>

HINSTANCE g_hInstance;
HWND childWnd;

void OnCreate(HWND hParent)
{
	childWnd = CreateWindowEx(0,__TEXT("edit"),NULL,WS_CHILD | WS_VISIBLE | WS_BORDER,0,0,100,100,hParent,NULL,g_hInstance,NULL);
}

void OnSize(HWND hWnd,LPARAM lParam)
{
	int nWidth = LOWORD(lParam);
	int nHight = HIWORD(lParam);
	MoveWindow(childWnd,0,0,nWidth,nHight,TRUE);
}

//視窗處理函式
LRESULT CALLBACK WinProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
	switch(uMsg)
	{
		/*
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
		*/
	case WM_SIZE:
		OnSize(hWnd,lParam);
		break;
	case WM_CREATE:
		OnCreate(hWnd);
		break;
	case WM_SYSCOMMAND:
		if (SC_CLOSE == wParam)
		{
			if(IDYES == MessageBox(hWnd,__TEXT("確定是否關閉視窗"),__TEXT("提示"),MB_YESNO))
			{
				PostQuitMessage(0);
			}
			//不加else處理,程式會執行DefWindowProc,視窗程序不能關閉
			else
				return 0;
		}
break;
	}
	return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
//註冊視窗類
BOOL Register(LPCWSTR className)
{
	WNDCLASSEX wc = {0};
	wc.cbClsExtra = 0;
	wc.cbSize = sizeof(WNDCLASSEX);
	wc.cbWndExtra = 0;
	wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
	wc.hCursor = NULL;
	wc.hIcon = NULL;
	wc.hIconSm = NULL;
	wc.hInstance = g_hInstance;
	wc.lpfnWndProc = WinProc;
	wc.lpszClassName = className;
	wc.lpszMenuName = NULL;
	wc.style = CS_HREDRAW | CS_VREDRAW;
	return RegisterClassEx(&wc);
}
//建立視窗
HWND CreateWin(LPCWSTR className,LPCWSTR winName)
{
	return CreateWindowEx(0,className,winName,WS_OVERLAPPEDWINDOW,100,100,600,600,NULL,NULL,g_hInstance,NULL);
}
//顯示和更新視窗
void ShowWin(HWND hWnd)
{
	ShowWindow(hWnd,SW_SHOW);
	UpdateWindow(hWnd);
}
//訊息迴圈
void Message()
{
	MSG ms = {0};
	while (GetMessage(&ms,NULL,0,0))
	{
		TranslateMessage(&ms);
		DispatchMessage(&ms);
	}
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
	g_hInstance = hInstance;
	Register(__TEXT("Main"));
	HWND hWnd = CreateWin(__TEXT("Main"),__TEXT("This is test"));
	ShowWin(hWnd);
	Message();
	return 0;
}