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

Windows SDK 筆記(一):Windows 程式基本架構與訊息機制核心

     編輯:關於VC++

Windows 程式固定架構

Windows 程式具有相對固定結構,開發者只需填寫系統預留的核心部分:視窗類別定義、視窗建立、訊息函式撰寫、訊息迴路。

核心組件詳解

1. 訊息處理函式

Windows 程式是事件驅動。每個視窗有訊息處理函式,系統處理大部分例行維護。開發者將處理函式與視窗關聯,有訊息產生時自動調用。通常只處理感興趣的訊息,其餘交由系統預設處理函式 DefWindowProc。

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_DESTROY:
            PostQuitMessage(0);  // 發送退出訊息結束訊息迴路
            return 0;
    }
    return ::DefWindowProc(hwnd, message, wParam, lParam);
}

2. 視窗建立流程

建立視窗獲得系統回傳控制代碼 (HWND),後續操作皆針對控制代碼。

  1. 註冊視窗類別:填寫 WNDCLASS 結構,核心是關聯訊息處理函式,其他屬性含功能表、圖示等。系統預定義類別(按鈕等控制項)無需自行註冊,直接使用類別名稱。
  2. 建立視窗:以註冊類別名稱為參數呼叫 CreateWindow,系統據此調用類別中指定的處理函式。

3. 訊息迴路

系統將訊息放入程式「訊息佇列」,程式依序取出、分派至對應視窗。建立視窗後進入迴路,直到取得退出訊息 (WM_QUIT) 結束。

MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
    TranslateMessage(&msg);   // 轉換鍵盤訊息 (WM_KEYDOWN → WM_CHAR)
    DispatchMessage(&msg);    // 分派至視窗處理函式
}

完整最小可執行程式範例

#include 

// 1. 訊息處理函式
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
    }
    return ::DefWindowProc(hwnd, message, wParam, lParam);
}

// 2. 應用程式進入點
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    PSTR szCmdLine, int iCmdShow)
{
    // 註冊視窗類別
    static TCHAR szAppName[] = TEXT("HelloWin");
    WNDCLASS wndclass = {0};
    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("註冊失敗!"), szAppName, MB_ICONERROR);
        return 0;
    }

    // 建立視窗
    HWND hwnd = CreateWindow(szAppName, TEXT("The Hello Program"),
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
        NULL, NULL, hInstance, NULL);

    ShowWindow(hwnd, iCmdShow);
    UpdateWindow(hwnd);

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

關鍵結構體與參數解析

WNDCLASS 結構體

欄位用途常用值
style類別樣式CS_HREDRAW \| CS_VREDRAW (水平/垂直重繪)
lpfnWndProc訊息處理函式指標WndProc
cbClsExtra / cbWndExtra額外記憶體位元組通常 0
hInstance應用程式實例控制代碼WinMain 參數 hInstance
hIcon類別圖示LoadIcon(NULL, IDI_APPLICATION)
hCursor類別游標LoadCursor(NULL, IDC_ARROW)
hbrBackground背景筆刷GetStockObject(WHITE_BRUSH)
lpszMenuName功能表資源名稱NULL 或 MAKEINTRESOURCE(IDR_MENU)
lpszClassName類別名稱字串自訂唯一名稱

CreateWindow 關鍵參數

參數說明常用值
lpClassName視窗類別名稱註冊時的 lpszClassName
lpWindowName視窗標題列文字TEXT("標題")
dwStyle視窗樣式WS_OVERLAPPEDWINDOW (標準主視窗)
x, y初始位置CW_USEDEFAULT (系統決定)
nWidth, nHeight初始大小CW_USEDEFAULT
hWndParent父視窗控制代碼NULL (主視窗無父視窗)
hMenu功能表/子視窗 IDNULL 或 (HMENU)ID
hInstance實例控制代碼WinMain 參數
lpParam建立參數傳給 WM_CREATENULL 或自訂結構指標

訊息機制核心概念

訊息結構 (MSG)

typedef struct tagMSG {
    HWND hwnd;        // 接收視窗
    UINT message;     // 訊息識別碼
    WPARAM wParam;    // 32 位元參數 1
    LPARAM lParam;    // 32 位元參數 2
    DWORD time;       // 訊息建立時間
    POINT pt;         // 滑鼠螢幕座標
} MSG;

訊息分類

  • 佇列訊息:經由訊息佇列,如滑鼠、鍵盤、計時器、繪圖、退出
  • 非佇列訊息:直接發送至視窗程式,如 WM_ACTIVATE、WM_SETFOCUS、API 呼叫產生的訊息

訊息傳送 vs 佇列

函式行為回傳時機
SendMessage同步發送,直接呼叫視窗程式處理完成後回傳
PostMessage非同步佇列,放入訊息佇列放入佇列即回傳

常見訊息處理模式

switch (message)
{
    case WM_CREATE:
        // 初始化、建立子視窗、配置資源
        return 0;

    case WM_PAINT:
        // 繪圖邏輯
        return 0;

    case WM_COMMAND:
        // 功能表/控制項命令
        return 0;

    case WM_SIZE:
        // 視窗大小變更,重新配置版面
        return 0;

    case WM_TIMER:
        // 計時器觸發
        return 0;

    case WM_DESTROY:
        // 清理資源、發送退出訊息
        PostQuitMessage(0);
        return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);

現代開發建議

  • 優先使用框架:MFC、WTL、Win32++ 等封裝基礎架構
  • Unicode 專案:預設使用 TCHAR/TEXT() 宏支援雙版本
  • DPI 感知:Manifest 宣告 dpiAware 或 PerMonitorV2
  • 錯誤處理:檢查所有 API 回傳值,善用 GetLastError
  • 資源管理:RAII 模式管理 GDI 物件、記憶體、控制代碼
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved