首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

Windows API 入門 (三):視窗類別註冊、建立、顯示完整流程詳解

     編輯:VC 教學

視窗初始化四步驟

  1. 定義視窗類別 (WNDCLASS/WNDCLASSEX)
  2. 註冊視窗類別 (RegisterClass)
  3. 建立視窗實例 (CreateWindow/CreateWindowEx)
  4. 顯示與更新 (ShowWindow, UpdateWindow)

步驟 1:視窗類別定義核心函數

LoadIcon - 載入圖示


HICON LoadIcon(
    HINSTANCE hInstance,   // 模組句柄,NULL = 系統預設
    LPCTSTR lpIconName     // 資源名或 MAKEINTRESOURCE(IDI_*)
);
  • 系統預設:IDI_APPLICATION, IDI_HAND, IDI_QUESTION, IDI_EXCLAMATION, IDI_ASTERISK, IDI_WINLOGO。

LoadCursor - 載入游標


HCURSOR LoadCursor(
    HINSTANCE hInstance,    // NULL = 系統預設
    LPCTSTR lpCursorName    // IDC_ARROW, IDC_IBEAM, IDC_WAIT, IDC_CROSS, IDC_SIZEALL...
);

GetStockObject - 取得系統股票物件


HGDIOBJ GetStockObject(int fnObject);
// 常用:WHITE_BRUSH, BLACK_BRUSH, GRAY_BRUSH, DKGRAY_BRUSH, NULL_BRUSH,
//       SYSTEM_FONT, DEFAULT_GUI_FONT, SYSTEM_FIXED_FONT

WNDCLASS 完整填寫範例


WNDCLASS wc = {0};
wc.style         = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; // 重繪風格 + 雙擊支援
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)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName  = MAKEINTRESOURCE(IDR_MAINMENU); // 或 NULL
wc.lpszClassName = TEXT("MyWindowClass");

步驟 2:註冊視窗類別


if (!RegisterClass(&wc)) {
    MessageBox(NULL, TEXT("註冊失敗"), TEXT("錯誤"), MB_ICONERROR);
    return 0;
}
// 成功返回類別原子 (ATOM),失敗返回 0

步驟 3:建立視窗實例 - CreateWindow 詳解


HWND CreateWindow(
    LPCTSTR lpClassName,   // 註冊類別名
    LPCTSTR lpWindowName,  // 視窗標題
    DWORD dwStyle,         // 視窗風格 (WS_*)
    int x, int y,          // 左上角座標 (CW_USEDEFAULT = 系統決定)
    int nWidth, int nHeight, // 寬高
    HWND hWndParent,       // 父視窗句柄 (NULL = 無)
    HMENU hMenu,           // 選單句柄 / 子視窗 ID
    HINSTANCE hInstance,   // 模組句柄
    LPVOID lpParam         // 傳遞給 WM_CREATE 的 lpCreateParams
);

常用視窗風格 (WS_*) 組合表

風格值效果
WS_OVERLAPPED0x00000000重疊視窗 (有標題列、邊框)
WS_POPUP0x80000000彈出視窗 (無標題列、邊框)
WS_CHILD0x40000000子視窗 (必須有父視窗)
WS_MINIMIZE0x20000000初始最小化
WS_VISIBLE0x10000000初始可見
WS_DISABLED0x08000000初始停用
WS_CLIPSIBLINGS0x04000000裁剪同層兄弟視窗
WS_CLIPCHILDREN0x02000000裁剪子視窗區域
WS_MAXIMIZE0x01000000初始最大化
WS_CAPTION0x00C00000標題列 (包含 WS_BORDER | WS_DLGFRAME)
WS_BORDER0x00800000細邊框
WS_DLGFRAME0x00400000對話框邊框 (無標題)
WS_VSCROLL0x00200000垂直捲軸
WS_HSCROLL0x00100000水平捲軸
WS_SYSMENU0x00080000系統選單 (關閉/移動/大小/最小化/最大化)
WS_THICKFRAME0x00040000可調整大小邊框 (含 WS_BORDER)
WS_GROUP0x00020000控制項群組首項 (Tab 導航)
WS_TABSTOP0x00010000可接收焦點 (Tab 鍵)

預定義組合風格

  • WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX
  • WS_POPUPWINDOW = WS_POPUP | WS_BORDER | WS_SYSMENU
  • WS_CHILDWINDOW = WS_CHILD

風格組合技巧:位元 OR (|)


// 同時擁有垂直與水平捲軸的彈出視窗
DWORD style = WS_POPUP | WS_VSCROLL | WS_HSCROLL | WS_SYSMENU;

步驟 4:顯示與更新


// ShowWindow 顯示狀態控制
BOOL ShowWindow(HWND hWnd, int nCmdShow);
// nCmdShow 常用值:
// SW_HIDE (0), SW_SHOWNORMAL (1), SW_SHOWMINIMIZED (2), SW_SHOWMAXIMIZED (3),
// SW_SHOWNOACTIVATE (4), SW_RESTORE (9)

// UpdateWindow 強制發送 WM_PAINT
BOOL UpdateWindow(HWND hWnd);

完整流程整合範例


int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, int nShow)
{
    // 1. 類別定義
    WNDCLASS wc = {0};
    wc.lpfnWndProc = WndProc;
    wc.hInstance = hInst;
    wc.lpszClassName = TEXT("DemoClass");
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    RegisterClass(&wc);

    // 2. 建立視窗
    HWND hwnd = CreateWindow(
        TEXT("DemoClass"), TEXT("API Demo"),
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, 640, 480,
        NULL, NULL, hInst, NULL);

    // 3. 顯示
    ShowWindow(hwnd, nShow);
    UpdateWindow(hwnd);

    // 4. 訊息迴圈
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}

常見錯誤與對策

錯誤原因修正
RegisterClass 失敗類別名重複、結構體未歸零使用唯一名稱、WNDCLASS wc = {0};
CreateWindow 返回 NULL類別未註冊、風格衝突 (如 WS_CHILD 無父視窗)檢查 GetLastError(),確認父視窗有效
視窗不顯示未呼叫 ShowWindow/UpdateWindow務必呼叫兩者
背景不重繪hbrBackground 為 NULL 或未處理 WM_ERASEBKGND設定股票刷子或自行處理 WM_ERASEBKGND

視窗建立完整流程圖

這四個步驟構成了所有 Windows GUI 程式的基石,熟練掌握每個參數含義,是進階開發的前提。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved