完整代碼注釋
#include <Windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT("HelloWin");
HWND hwnd;
MSG msg;
// 視窗類,指定基本的視窗資訊,CreateWindow參數指定更詳細的資訊
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW; // 視窗類樣式
wndclass.lpfnWndProc = WndProc; // 視窗消息處理程式
wndclass.cbClsExtra = 0; // 視窗類結構預留白間
wndclass.cbWndExtra = 0; // Windows内部預留白間
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,// initial x position
CW_USEDEFAULT,// initial y position
CW_USEDEFAULT,// initial x size
CW_USEDEFAULT,// initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL); // creation parameters
// 在顯示器上顯示視窗,第二個參數:正常、最大化、最小化、隐藏
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd); // 重畫顯示區域,發送消息給消息處理程式
while (GetMessage(&msg, NULL, 0, 0)) // 從消息隊列擷取消息
{
TranslateMessage(&msg); // 将msg結構傳給Windows,進行一些鍵盤轉換
DispatchMessage(&msg); // 調用消息處理程式
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam,
LPARAM lParam) // 視窗消息處理程式的四個參數與MSG結構的前四個字段是相同的
{
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
switch (message) {
case WM_CREATE: // 視窗建立時,處理WM_CREATE消息
// 播放聲音檔案
PlaySound(TEXT("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC);
return 0; // 必須傳回0
case WM_PAINT: // 更新畫面時,處理WM_PAINT消息
hdc = BeginPaint(hwnd, &ps); // 獲得裝置内容句柄
GetClientRect(hwnd, &rect); // 設定RECT坐标(視窗大小)
DrawText(hdc, TEXT("你好視窗!"), -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint(hwnd, &ps); // 釋放裝置内容句柄
return 0;
case WM_DESTROY: // 處理WM_DESTROY消息
// 在程式的消息隊列中插入一個WM_QUIT消息,GetMessage會傳回0,退出消息循環
PostQuitMessage(0);
return 0;
}
// 不予處理的所有消息應該被傳給名為DefWindowProc
return
播放WAV
VS2015引入WINMM.LIB,用來播放WAV:工程,右鍵屬性,連結器,輸入,附加依賴項
調用的Windows函數
LoadIcon 加載圖示供程式使用。
LoadCursor 加載滑鼠光标供程式使用。
GetStockObject 取得一個圖形對象(在這個例子中,是取得繪制視窗背景的畫刷對象)。
RegisterClass 為程式視窗注冊視窗類别。
MessageBox 顯示消息框。
CreateWindow 根據視窗類别建立一個視窗。
ShowWindow 在螢幕上顯示視窗。
UpdateWindow 訓示視窗自我更新。
GetMessage 從消息隊列中取得消息。
TranslateMessage 轉譯某些鍵盤消息。
DispatchMessage 将消息發送給視窗消息處理程式。
PlaySound 播放一個聲音檔案。
BeginPaint 開始繪制視窗。
GetClientRect 取得視窗顯示區域的大小。
DrawText 顯示字元串。
EndPaint 結束繪制視窗。
PostQuitMessage 在消息隊列中插入一個「退出程式」消息。
DefWindowProc 執行内定的消息處理。
大寫字母辨別
字首 | 類别 | 英文 |
CS | 視窗類别樣式 | class style |
CW | 建立視窗 | create window |
DT | 繪制文字 | draw text |
IDI | 圖示ID | ID icon |
IDC | 遊标ID | ID cursor |
MB | 消息框 | message border |
SND | 聲音 | sound |
WM | 視窗消息 | window message |
WS | 視窗樣式 | window style |
四種資料結構
結構 | 含義 |
MSG | 消息結構 |
WNDCLASS | 視窗類别結構 |
PAINTSTRUCT | 繪圖結構 |
RECT | 矩形結構 |
/*
* 消息資料結構
*/
typedef struct tagMSG {
HWND hwnd; // 接收消息的視窗句柄
UINT message; // 消息辨別符
WPARAM wParam; // 32位的消息參數(message parameter)
LPARAM lParam; // 32位的消息參數
DWORD time; // 放入消息隊列中的時間
POINT pt; // 消息放入消息隊列時的滑鼠坐标
#ifdef _MAC
DWORD lPrivate;
#endif
} MSG, *PMSG, NEAR *NPMSG, FAR *LPMSG;
WM_QUIT消息将導緻GetMessage傳回0
大寫辨別符
句柄是一個(通常為32位的)整數,它代表一個對象。
辨別符 | 含義 |
HINSTANCE | 執行實體(程式自身)句柄 |
HWND | 視窗句柄 |
HDC | 裝置内容句柄 |
HICON | 圖示句柄 handle to an icon |
HCURSOR | 滑鼠光标句柄 |
HBRUSH | 畫刷句柄 |
匈牙利表示法
字首 | 資料型态 |
c | char或WCHAR或TCHAR |
by | BYTE (無正負号字元) |
n | short |
i | int |
x, y | int分别用作x坐标和y坐标 |
cx, cy | int分别用作x長度和y長度;C代表「計數器」 |
b或f | BOOL (int);f代表「旗标」 |
w | WORD (無正負号短整數) |
l | LONG (長整數) |
dw | DWORD (無正負号長整數) |
fn | function(函數) |
s | string(字元串) |
sz | 以位元組值0結尾的字元串 |
h | 句柄 |
p | 名額 |
消息中心
假設使用者執行HELLOWIN,并且使用者最終單擊了 Close按鈕,或者假設用鍵盤或滑鼠從系統菜單中選擇了 Close, DefWindowProc處理這一鍵盤或者滑鼠輸入,在檢測到使用者選擇了Close選項之後,它給視窗消息處理程式發送一條WM_SYSCOMMAND消息。WndProc将這個消息傳給DefWindowProc。DefWindowProc給視窗消息處理程式發送一條WM_CLOSE消 息 來 響 應 之 。 WndProc 再 次 将 它 傳 給 DefWindowProc 。 DestroyWindow 呼 叫DestroyWindow來響應這條WM_CLOSE消息。DestroyWindow導緻Windows給視窗消息處理程式發送一條WM_DESTROY消息。WndProc再呼叫PostQuitMessage,将一條WM_QUIT消息放入消息隊列中,以此來響應此消息。這個消息導緻WinMain中的消息循環終止,然後程式結束。
消息能夠被分為「隊列化的」和「非隊列化的」。隊列化的消息是由Windows放入程式消息隊列中的。在程式的消息循環中,重新傳回并配置設定給視窗消息處理程式。非隊列化的消息在Windows呼叫視窗時直接送給視窗消息處理程式。也就是說,隊列化的消息被「發送」給消息隊列,而非隊列化的消息則「發送」給視窗消息處理程式。任何情況下,視窗消息處理程式都将獲得視窗所有的消息–包括隊列化的和非隊列化的。
視窗消息處理程式是視窗的”消息中心”。