#include
int main() {
printf("Hello world\n");
return 0;
}
最基礎的 C 程式,輸出到主控台視窗。
#include
int main() {
MessageBox(NULL, "Hello World", "window", MB_OK);
return 0;
}
雖然呼叫了 MessageBox,但仍是主控台子系統,執行時會出現黑底視窗。
#include
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow) {
MessageBox(NULL, "Hello World", "window", MB_OK);
return 0;
}
關鍵差異:
WinMain/SUBSYSTEM:WINDOWS (VC6: Project → Settings → Link → Subsystem: Windows)建立真正的視窗需完成:視窗類別註冊 → 建立視窗 → 訊息迴圈 → 視窗程序。
#include
// 視窗程序前向宣告
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow) {
HWND hwnd;
MSG msg;
WNDCLASS wc = {0};
// 1. 設定視窗類別
wc.hbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH); // 深灰背景
wc.hInstance = hInst;
wc.lpfnWndProc = WndProc;
wc.lpszClassName = "test";
wc.style = CS_VREDRAW | CS_HREDRAW; // 垂直/水平重繪
// 2. 註冊視窗類別
if (!RegisterClass(&wc)) return 0;
// 3. 建立視窗
hwnd = CreateWindow("test", "test", WS_OVERLAPPED | WS_SYSMENU,
0, 0, 300, 200, NULL, NULL, hInst, NULL);
if (!hwnd) return 0;
// 4. 顯示與更新
ShowWindow(hwnd, nShow);
UpdateWindow(hwnd);
// 5. 訊息迴圈
while (TRUE) {
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
if (msg.message == WM_QUIT) break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return 0;
}
// 視窗程序:處理視窗訊息
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
case WM_DESTROY:
PostQuitMessage(0); // 發送 WM_QUIT 結束迴圈
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam); // 預設處理
}
return 0;
}
| 元素 | 說明 |
|---|---|
| WNDCLASS | 視窗類別結構,定義視窗行為與外觀 |
| RegisterClass | 向系統註冊視窗類別 |
| CreateWindow | 依類別建立視窗實體 |
| ShowWindow / UpdateWindow | 顯示視窗並觸發首次 WM_PAINT |
| PeekMessage / GetMessage | 從佇列取得訊息 (PeekMessage 不阻塞) |
| TranslateMessage | 將虛擬鍵訊息轉為字元訊息 (WM_CHAR) |
| DispatchMessage | 將訊息分派給視窗程序 |
| WndProc | 視窗程序,處理特定訊息 |
| DefWindowProc | 預設視窗程序,處理未自行處理的訊息 |
| WM_DESTROY | 視窗銷毀時發送,應呼叫 PostQuitMessage |
WinMain 與 main 差異WndProc 處理 WM_PAINT、WM_KEYDOWN、WM_MOUSEMOVE 等常用訊息