#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // 聲明窗口過(guò)程函數(shù),后面有定義
/*程序入口點(diǎn)WinMain函數(shù)*/ int WINAPI WinMain(HINSTANCE hInstance, // 第一個(gè)參數(shù)為程序?qū)嵗浔?,用于?biāo)識(shí)該程序 HINSTANCE hPrevInstance, // 第二個(gè)參數(shù)用于同一程序多次運(yùn)行時(shí)的標(biāo)識(shí),但在win32中不再使用,為NULL LPSTR lpCmdLine, // 第三個(gè)參數(shù)為程序運(yùn)行參數(shù) int nShowCmd) // 第四個(gè)參數(shù)為程序運(yùn)行的初始狀態(tài)(最小化、正常、最大化) { static TCHAR szAppName[] = TEXT("HelloWin"); // 定義一個(gè)字符串,保存程序的名字,自由定義 HWND hwnd; // 定義一個(gè)句柄,以備后面創(chuàng)建窗體時(shí)使用 MSG msg; // 定義一個(gè)消息結(jié)構(gòu),用于后面的消息循環(huán) WNDCLASS wndclass; // 定義一個(gè)窗口類結(jié)構(gòu)體,該結(jié)構(gòu)體名為wndclass,并在下面幾行設(shè)置結(jié)構(gòu)體內(nèi)的數(shù)據(jù) wndclass.style = CS_HREDRAW | CS_VREDRAW; // CS_HREDRAW為水平方向尺寸,CS_VREDRAW為垂直方向尺寸,這兩個(gè)標(biāo)識(shí)用于后面調(diào)整窗體大小時(shí),中央文本能任意顯示在中央 wndclass.lpfnWndProc = WndProc; // 將這個(gè)窗口類的過(guò)程設(shè)置為WndProc過(guò)程函數(shù),這個(gè)過(guò)程處理基于這個(gè)窗口類創(chuàng)建的所有窗口的全部消息,lpfnWndProc為指向WndProc函數(shù)的指針 wndclass.cbClsExtra = 0; // 用于在類結(jié)構(gòu)和windows內(nèi)部保存的窗口結(jié)構(gòu)中預(yù)留一些額外空間,程序可以根據(jù)需要來(lái)使用預(yù)留的空間 wndclass.cbWndExtra = 0; // 同上 wndclass.hInstance = hInstance; // 程序的實(shí)例句柄,由于該窗口屬于該程序,這里與WinMain函數(shù)中的第一個(gè)參數(shù)一致 wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); // 加載圖標(biāo)供應(yīng)用程序使用,這里使用系統(tǒng)自帶的預(yù)定義的圖標(biāo),第一個(gè)參數(shù)為NULL,第二個(gè)參數(shù)IDI_APPLICATION是一個(gè)簡(jiǎn)單的窗口小圖標(biāo),如果要用自己準(zhǔn)備的圖標(biāo),第一個(gè)參數(shù)為程序?qū)嵗浔?,第二個(gè)參數(shù)標(biāo)識(shí)圖標(biāo) wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); // 加載鼠標(biāo)指針供程序使用, LoadCursor函數(shù)加載一個(gè)預(yù)定義的鼠標(biāo)光標(biāo),光標(biāo)樣式為IDC_ARROW,并返回該光標(biāo)的句柄,這樣,當(dāng)我們將鼠標(biāo)放到窗體客戶區(qū)上時(shí),鼠標(biāo)變成一個(gè)小箭頭,若果第二個(gè)參數(shù)是其他樣式,則鼠標(biāo)放在客戶區(qū)上時(shí),顯示不一樣的光標(biāo) wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); // 獲取繪制窗口背景的刷子,GetStockObject函數(shù)返回一個(gè)刷子句柄,參數(shù)WHITE_BRUSH為白色刷子,所以這里返回的是白色刷子句柄,也可以設(shè)置其他顏色,這決定著窗口客戶端的背景顏色 wndclass.lpszMenuName = NULL; // 指定窗口類菜單,這里不需要菜單,為空 wndclass.lpszClassName = szAppName; // 設(shè)置一個(gè)類名,自由定義,這里我們定義為開(kāi)頭定義的szAppName[] RegisterClass(&wndclass); // 注冊(cè)剛剛定義的窗口類
/*根據(jù)窗口類創(chuàng)建一個(gè)窗口,返回一個(gè)窗口句柄保存在hwnd里,同時(shí)下面的參數(shù)指定有關(guān)該窗口更多信息*/ hwnd = CreateWindow(szAppName, // 第一個(gè)參數(shù)為程序注冊(cè)的窗口類的名稱 TEXT("The Hello Program"), // 第二個(gè)參數(shù)為窗口標(biāo)題欄的內(nèi)容 WS_OVERLAPPEDWINDOW, // 第三個(gè)參數(shù)為窗口風(fēng)格,這里WS_OVERLAPPEDWINDOW是一種標(biāo)準(zhǔn)的窗口風(fēng)格,它有一個(gè)標(biāo)題欄,標(biāo)題欄左邊有一個(gè)系統(tǒng)菜單框,標(biāo)題欄右邊有最小化、最大化和關(guān)閉按鈕,四周還有表示窗口大小的邊框 CW_USEDEFAULT, // 第四個(gè)參數(shù)為窗口在屏幕上的水平位置,這里使用默認(rèn)位置 CW_USEDEFAULT, // 第五個(gè)參數(shù)為窗口在屏幕上的垂直位置,這里也是用默認(rèn)位置 CW_USEDEFAULT, // 第六個(gè)參數(shù)為窗口寬度,這里使用默認(rèn)位置 CW_USEDEFAULT, // 第七個(gè)參數(shù)為窗口高度,這里也是用默認(rèn)位置 NULL, // 第八個(gè)參數(shù)為父窗口句柄,由于這個(gè)程序只有一個(gè)窗口,這個(gè)窗口就是最高級(jí)窗口,所以這里留空 NULL, // 第九個(gè)參數(shù)為窗口菜單句柄,這里沒(méi)有菜單,也留空 hInstance, // 第十個(gè)參數(shù)為程序?qū)嵗浔?,與前面一樣都為hInstance NULL); // 最后為創(chuàng)建參數(shù)指針為NULL,可以用這個(gè)指針訪問(wèn)以后想要引用的程序中的數(shù)據(jù) ShowWindow(hwnd, nShowCmd); // 在屏幕上顯示該窗口,參數(shù)hwnd即為剛剛創(chuàng)建好的窗口句柄,nShowCmd即WinMain函數(shù)的第四個(gè)參數(shù),決定窗口初始的狀態(tài),正常、最小化或最大化 UpdateWindow(hwnd); // 使窗口刷新自身
while (GetMessage(&msg, NULL, 0, 0)) // 進(jìn)入消息循環(huán),GetMessage函數(shù)每執(zhí)行一次從消息隊(duì)列中取出一個(gè)消息,參數(shù)NULL,0,0表示程序接受屬于它的所有窗口的所有消息 { TranslateMessage(&msg); // 將msg結(jié)構(gòu)傳遞給windows,轉(zhuǎn)換一些鍵盤消息 DispatchMessage(&msg); // 該函數(shù)將msg結(jié)構(gòu)傳給windows,然后windows將該消息發(fā)送給適當(dāng)?shù)拇翱谶^(guò)程,讓它處理,本程序中窗口過(guò)程即WndProc函數(shù) } return msg.wParam; // 當(dāng)退出消息循環(huán)后,返回msg結(jié)構(gòu)的wParam數(shù)據(jù),該數(shù)據(jù)是傳遞給PostQuitMessage函數(shù)的值(通常是0) }
/*定義窗口過(guò)程,窗口過(guò)程確定了在窗口的客戶區(qū)域顯示什么,以及窗口怎樣響應(yīng)用戶的輸入*/ LRESULT CALLBACK WndProc(HWND hwnd, // 第一個(gè)參數(shù)hwnd是接收消息的窗口的句柄 UINT message, // 第二個(gè)參數(shù)message是標(biāo)識(shí)該消息的數(shù)字 WPARAM wParam, // 32位的消息參數(shù),提供了關(guān)于消息的更多信息 LPARAM lParam) // 32位的消息參數(shù),提供了關(guān)于消息的更多信息 { HDC hdc; // 定義一個(gè)設(shè)備描述表句柄,這里指顯示輸入設(shè)備句柄 PAINTSTRUCT ps; // 該結(jié)構(gòu)體內(nèi)包含了一些窗口過(guò)程,用來(lái)刷新窗口客戶區(qū)的內(nèi)容 RECT rect; // 定義一個(gè)RECT結(jié)構(gòu)體,用于后面保存窗口客戶區(qū)域的尺寸
switch (message) // 處理消息,這里我們定義的WndProc過(guò)程窗口函數(shù)只處理兩種消息 { case WM_PAINT: // 當(dāng)我們調(diào)整窗口邊框時(shí),整個(gè)窗口將變成無(wú)效的,窗口過(guò)程收到此WM_PAINT消息,接下來(lái)我們需要重新繪制窗口,這也是使得中央文本能一直保持在中央的原因 hdc = BeginPaint(hwnd, &ps); // 開(kāi)始窗口繪制,第一個(gè)參數(shù)為程序的窗口句柄,第二個(gè)參數(shù)為指向PAINTSTRUCT結(jié)構(gòu)體的指針,該結(jié)構(gòu)體內(nèi)包含一些窗口過(guò)程,用來(lái)刷新窗口客戶區(qū)的內(nèi)容。BeginPaint函數(shù)返回一個(gè)設(shè)備描述表句柄,保存在hdc里 GetClientRect(hwnd, &rect); // 獲取窗口客戶區(qū)的尺寸,第二個(gè)參數(shù)為之前定義的RECT結(jié)構(gòu)體,用于保存窗口客戶區(qū)域的尺寸 DrawText(hdc, TEXT("Hello, Windows XP!"), -1, &rect, // 顯示窗口中心文本,第一個(gè)參數(shù)為設(shè)備表描述句柄,第二個(gè)參數(shù)為要顯示的文本字符串,第三個(gè)參數(shù)為-1,指示字符串是以字符0結(jié)束的,第四個(gè)參數(shù)是保存客戶區(qū)尺寸的結(jié)構(gòu)體 DT_SINGLELINE|DT_CENTER|DT_VCENTER); EndPaint(hwnd, &ps); // 結(jié)束窗口繪制,參數(shù)同開(kāi)始窗口繪制 return 0; case WM_DESTROY: // 單機(jī)右上角關(guān)閉按鈕時(shí)觸發(fā)此消息 PostQuitMessage(0); // 在消息隊(duì)列中插入一條“退出”消息,這使得WinMain函數(shù)退出消息循環(huán),程序終止 return 0; } return DefWindowProc(hwnd, message, wParam, lParam); // DefWindowProc為默認(rèn)消息處理函數(shù),窗口過(guò)程不處理的消息傳遞給該函數(shù) }
|