最小 Win32 窗口程序
#include <windows.h>
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow) {
static TCHAR szAppName[] = TEXT("HelloWin");
HWND hwnd;
MSG msg;
WNDCLASS wndclass = {0};
// 1. 註冊窗口類
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.lpszClassName = szAppName;
if (!RegisterClass(&wndclass)) {
MessageBox(NULL, TEXT("Requires Windows NT!"), szAppName, MB_ICONERROR);
return 0;
}
// 2. 創建窗口
hwnd = CreateWindow(szAppName, TEXT("The Hello Program"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
// 3. 顯示與更新
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
// 4. 消息循環
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
// 窗口過程:處理消息
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
switch (msg) {
case WM_CREATE:
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rect);
DrawText(hdc, TEXT("Hello, Windows Program!"), -1, &rect,
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
EndPaint(hwnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
核心步驟解析
- WNDCLASS 註冊:定義窗口類屬性(風格、圖標、光標、背景刷、窗口過程指針、類名)。
RegisterClass 向系統登記。
- CreateWindow:根據類名創建窗口實例,返回窗口句柄
HWND。參數指定標題、風格、位置、大小、父窗口、菜單、實例句柄。
- ShowWindow / UpdateWindow:
ShowWindow 設置顯示狀態(最小化/最大化/正常),UpdateWindow 發送 WM_PAINT 強制繪製客戶區。
- 消息循環:
GetMessage 從隊列取消息(阻塞),TranslateMessage 將虛擬鍵消息轉為字符消息,DispatchMessage 分發給窗口過程 WndProc。
WndProc 關鍵消息
WM_CREATE:窗口創建時,初始化資源
WM_PAINT:客戶區需要繪製,BeginPaint/EndPaint 配對使用,獲取 HDC 繪圖
WM_DESTROY:窗口銷毀,調用 PostQuitMessage(0) 向隊列投遞 WM_QUIT 結束消息循環
DefWindowProc:默認處理未關心的消息(如移動、調整大小、非客戶區繪製)
WNDCLASS 關鍵字段
| 字段 | 作用 | 常用值 |
| style | 類風格 | CS_HREDRAW | CS_VREDRAW(尺寸變化重繪) |
| lpfnWndProc | 窗口過程指針 | WndProc |
| hInstance | 應用程序實例 | WinMain 第一參數 |
| hIcon / hCursor | 圖標/光標 | LoadIcon/LoadCursor 系統資源 |
| hbrBackground | 背景刷 | GetStockObject(WHITE_BRUSH) |
| lpszClassName | 類名字符串 | 唯一標識,CreateWindow 使用 |
常見問題
RegisterClass 失敗:通常是類名重複或 hInstance 錯誤
- 窗口不顯示:忘記
ShowWindow 或 UpdateWindow
- 繪製閃爍:雙緩衝或處理
WM_ERASEBKGND 返回 TRUE
- 中文亂碼:源文件保存為 UTF-8 with BOM,或使用
TEXT() 宏 + Unicode 版 API(CreateWindowW)