本文由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消息機制的工作原理
也許你初次看到這張圖,感覺密密麻麻的,不是很懂,别擔心,我将逐漸講解:
(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不放試試……
好了,今天到此為止吧,下次繼續了^_^