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

Windows 視窗類別註冊機制深度解析(上):從 SDK 到 MFC 的演進

     編輯:VC++

前言:什麼是視窗類別?

在 Windows 作業系統中,所有可見的視窗(按鈕、編輯框、主視窗等)在建立之前,系統必須知道如何繪製它、如何處理使用者輸入。這份「藍圖」就是視窗類別。注意:這裡的「類別」不是 C++ 的 class,而是一個 WNDCLASS/WNDCLASSEX 結構體,包含視窗風格、訊息處理函數、圖示、游標、背景筆刷、選單、類別名稱等資訊。

一、WNDCLASS 結構體詳細剖析

ANSI 版本定義如下:

typedef struct tagWNDCLASSA {
    UINT        style;          // 類別風格(CS_HREDRAW | CS_VREDRAW 等)
    WNDPROC     lpfnWndProc;    // 訊息處理函數指標
    int         cbClsExtra;     // 類別額外記憶體位元組
    int         cbWndExtra;     // 視窗實例額外記憶體位元組
    HINSTANCE   hInstance;      // 應用程式實例控制代碼
    HICON       hIcon;          // 視窗圖示
    HCURSOR     hCursor;        // 游標樣式
    HBRUSH      hbrBackground;  // 背景筆刷
    LPCSTR      lpszMenuName;   // 選單資源名稱
    LPCSTR      lpszClassName;  // 類別名稱(唯一識別字串)
} WNDCLASSA, *PWNDCLASSA;

填妥結構後,呼叫 RegisterClass 或 RegisterClassEx 向系統登記,後續即可用類別名稱呼叫 CreateWindow/CreateWindowEx 快速建立視窗,實現「一次註冊,多次建立」的複用機制。

二、傳統 SDK 程式中的視窗類別註冊流程

經典的 WinMain 入口點程式碼示範:

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;

    RegisterClass(&wndclass);

    HWND hwnd = CreateWindow(szAppName, TEXT("Hello"), 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;
}

流程清晰:填寫結構 → 註冊 → 建立視窗 → 訊息迴圈。一切由程式設計師手動控制。

三、MFC 如何封裝視窗類別註冊

使用 MFC 精靈建立專案時,我們看不到上述代碼,因為 MFC 在框架層已完成封裝。MFC 內建五個預設視窗類別(定義於 AFXIMPL.h 與 WINCORE.cpp):

巨集常數對應字串名稱用途
AFX_WND_REG"WND"一般視窗
AFX_WNDCONTROLBAR_REG"ControlBar"控制列
AFX_WNDMDIFRAME_REG"MDIFrame"MDI 主框架
AFX_WNDFRAMEORVIEW_REG"FrameOrView"框架/視圖
AFX_WNDOLECONTROL_REG"OleControl"OLE 控制項

這些字串最終由全域函式 AfxDeferRegisterClass 延遲註冊,核心邏輯在 AfxEndDeferRegisterClass 中呼叫 AfxRegisterClass → RegisterClass。下集將深入追蹤 MFC 如何在 CWnd::CreateEx → PreCreateWindow 鏈結中自動選擇正確類別。

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