補充前文遺漏的初始化細節。Windows API 程式初始化分四階段:
WNDCLASS/WNDCLASSEX)RegisterClass/RegisterClassEx)CreateWindow/CreateWindowEx)ShowWindow/UpdateWindow)
WNDCLASS wc = {0};
wc.style = CS_HREDRAW | CS_VREDRAW; // 水平/垂直縮放時重繪
wc.lpfnWndProc = WndProc; // 視窗程序指標
wc.cbClsExtra = 0; // 類別額外記憶體
wc.cbWndExtra = 0; // 視窗實例額外記憶體
wc.hInstance = hInstance; // 應用程式實例控制代碼
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); // 預設圖示
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // 預設箭頭游標
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); // 系統視窗背景色刷子
wc.lpszMenuName = NULL; // 無選單
wc.lpszClassName = TEXT("MyWindowClass"); // 類別名稱 (唯一字串)
| 函數 | 用途 | 參數說明 |
|---|---|---|
| LoadIcon | 載入圖示 | hInstance: 模組控制代碼 (NULL=系統圖示), lpIconName: 資源名/系統圖示 ID (如 IDI_APPLICATION) |
| LoadCursor | 載入游標 | hInstance: 模組控制代碼 (NULL=系統游標), lpCursorName: 資源名/系統游標 ID (如 IDC_ARROW) |
| GetStockObject | 取得系統預設 GDI 物件 | nObject: 物件類型 (WHITE_BRUSH, BLACK_PEN, SYSTEM_FONT 等) |
if (!RegisterClass(&wc)) {
MessageBox(NULL, TEXT("視窗類別註冊失敗"), TEXT("錯誤"), MB_ICONERROR);
return FALSE;
}
RegisterClassEx 使用 WNDCLASSEX 結構,多支援小圖示 (hIconSm) 與結構大小欄位 (cbSize)。
HWND hWnd = CreateWindow(
TEXT("MyWindowClass"), // lpClassName: 註冊的類別名
TEXT("我的第一個視窗"), // lpWindowName: 視窗標題
WS_OVERLAPPEDWINDOW, // dwStyle: 視窗風格
CW_USEDEFAULT, CW_USEDEFAULT, // x, y: 位置 (預設)
CW_USEDEFAULT, CW_USEDEFAULT, // nWidth, nHeight: 大小 (預設)
NULL, // hWndParent: 父視窗 (無)
NULL, // hMenu: 選單控制代碼 (無)
hInstance, // hInstance: 應用程式實例
NULL // lpParam: 建立參數 (無)
);
| 風格常數 | 效果 |
|---|---|
| WS_OVERLAPPEDWINDOW | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX (標準應用程式視窗) |
| WS_POPUP | 彈出式視窗 (無標題列、邊框) |
| WS_CHILD | 子視窗 (需指定父視窗) |
| WS_VISIBLE | 建立即顯示 (可省略 ShowWindow) |
| WS_HSCROLL / WS_VSCROLL | 水平/垂直捲軸 |
| WS_CLIPCHILDREN / WS_CLIPSIBLINGS | 繪製優化旗標 |
多重風格以位元 OR (|) 組合,如 WS_OVERLAPPEDWINDOW | WS_VSCROLL。
ShowWindow(hWnd, nCmdShow); // nCmdShow 來自 WinMain 參數
UpdateWindow(hWnd); // 強制繪製用戶區,發送 WM_PAINT
| 常數 | 行為 |
|---|---|
| SW_HIDE | 隱藏視窗 |
| SW_SHOWNORMAL | 正常顯示並啟動 (預設) |
| SW_SHOWMINIMIZED | 最小化顯示 |
| SW_SHOWMAXIMIZED | 最大化顯示 |
| SW_SHOWNOACTIVATE | 顯示但不啟動 (不取得焦點) |
| SW_RESTORE | 還原至原本位置大小 |
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow) {
// 1. 定義並註冊視窗類別
WNDCLASS wc = {0};
// ... 填充 wc ...
if (!RegisterClass(&wc)) return FALSE;
// 2. 建立視窗
HWND hWnd = CreateWindow(...);
if (!hWnd) return FALSE;
// 3. 顯示與更新
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
// 4. 訊息迴圈
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg); // 處理鍵盤訊息產生 WM_CHAR
DispatchMessage(&msg); // 分派至視窗程序
}
return (int)msg.wParam;
}
掌握初始化流程後,下一階段將學習 視窗程序 (WndProc) 撰寫與 GDI 繪圖 基礎。