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

系統理解 Win32 API 與 MFC (上):Win32 API 領域模型、核心物件與視窗體系

     編輯:關於VC++

前言

Win32 API 是 Windows 應用開發的基石,MFC 是其上層 C++ 封裝框架。本文嘗試以 UML/領域模型視角,系統梳理 Win32 API 核心概念:三大物件類別 (User/GDI/Kernel)、系統中斷轉訊息機制、視窗樹體系、訊息分類、視窗風格與類別,為深入理解 MFC 奠基。

1. 核心物件與系統關係

1.1 四大核心實體

  • Kernel Object:Process、Thread、File、Mutex、Event、Semaphore... 核心管理實體
  • User Object:Window、Menu、Hook、Icon、Cursor、Accelerator... 使用者介面實體
  • GDI Object:Bitmap、Brush、Pen、Font、Palette、Region、Path、DC... 繪圖實體
  • System (OS Core):負責「將硬體中斷封裝為訊息」投遞至執行緒訊息佇列

1.2 記憶體中運行關係圖

┌─────────────────────────────────────┐
│           System (OS)               │
│  中斷 → 訊息封裝 → 投遞至 Thread MQ  │
├─────────────────────────────────────┤
│  Kernel Objects                     │
│  File ←→ Module ←→ Process ←→ Thread │
│       (可執行檔)   (至少一條 Thread)  │
├─────────────────────────────────────┤
│  User Objects  ◄─── 擁有者: Thread   │
│  Window Tree (Desktop 為根)          │
├─────────────────────────────────────┤
│  GDI Objects   ◄─── 使用者: Thread   │
│  DC (容器) ← SelectObject → BMP/Font │
└─────────────────────────────────────┘

關鍵點:

  • 每個物件對應一個 Handle (句柄),核心物件 Handle 可跨進程繼承/複製
  • Thread 是核心:擁有訊息佇列、執行代碼、操作 User/GDI 物件
  • Process 至少一條 Thread,可執行檔載入為 Module,運行成為 Process
  • File ↔ Module ↔ Process ↔ Thread 形成靜態→動態轉換鏈

2. 系統中斷到訊息封裝

硬體中斷 (鍵盤/滑鼠/計時器/磁碟)
        │
        ▼
核心中斷處理常式 (ISR)
        │
        ▼
系統將中斷資訊封裝為 MSG 結構
        │
        ▼
投遞至目標 Thread 的訊息佇列 (Message Queue)
        │
        ▼
Thread 迴圈 GetMessage/DispatchMessage
        │
        ▼
呼叫視窗程序 WindowProc (或 AfxWndProc)

3. GDI 物件體系

  • 8 種基礎 GDI 物件:Bitmap、Brush、Pen、Region、Font、Palette、Path、DC (Device Context)
  • DC 是容器:
    • SelectObject:放入 Bitmap/Brush/Pen/Font/Region/Path
    • SelectPalette:放入 Palette
    • BeginPath/EndPath:放入 Path
  • DC 4 種:Display DC (螢幕繪圖)、Printer DC、Memory DC (離屏)、Information DC
  • 對應設計模式:Composite — DC 組合多種 GDI 物件統一繪圖介面

4. User 物件:視窗樹體系

4.1 視窗分類與樹結構 (第 1 次迭代)

Window Tree:
Desktop (根)
  ├─ Top-level Window (WS_OVERLAPPED / WS_POPUP)
  │     ├─ Child Window (WS_CHILD)
  │     │     └─ Child Window ...
  │     └─ ...
  └─ ...
每個節點記錄 4 指標:Parent、Child、Sibling (Brother)、Owner

4.2 CreateWindow 參數揭示的關係

HWND CreateWindow(
    LPCTSTR lpClassName,  // 窗口類別名 → 關聯 WNDCLASS
    LPCTSTR lpWindowName, // 標題
    DWORD dwStyle,        // WS_OVERLAPPED/POPUP/CHILD 等
    int x, y, w, h,
    HWND hWndParent,      // 父視窗 (Child 必填)
    HMENU hMenu,          // 選單/子視窗 ID
    HINSTANCE hInstance,  // 模組實例
    LPVOID lpParam        // 建立參數
);
關鍵:窗口類別 (WNDCLASS) 記錄 WindowProc、類別樣式、圖示、游標、背景筆刷、選單名、類別名
一個類別可對應多個視窗實例
模組 (hInstance) 是 WindowProc 與資源的「老家」

4.3 視窗風格深度解析 (第 2、3 次迭代)

風格本質分類典型用途CreateWindow dwStyle
WS_OVERLAPPEDTop-level Window標準應用程式主視窗WS_OVERLAPPEDWINDOW (含標題、邊框、系統選單、最小/最大化)
WS_POPUPTop-level Window (特殊 OVERLAPPED)對話框、工具視窗、無標題視窗WS_POPUP | WS_BORDER | WS_SYSMENU...
WS_CHILDChild Window控件 (Button/Edit/List)、子視圖WS_CHILD | WS_VISIBLE | WS_BORDER...

本質區別:

  • WS_CHILD:必須 有父視窗、座標相對父視窗客戶區、剪裁於父視窗內
  • WS_OVERLAPPED:獨立顯示、座標為螢幕座標、可有擁有者 (Owner) 但非父視窗
  • WS_POPUP:行為上屬於 WS_OVERLAPPED 特例,常用於對話框 (模態/非模態)

4.4 控件/對話框/一般視窗風格對應 (第 3 次迭代)

Control (按鈕/編輯/列表)  → 必須 WS_CHILD
Dialog (對話框)            → 必須 WS_POPUP (通常 WS_POPUP | WS_CAPTION | WS_SYSMENU)
一般視窗                   → 任意風格 (OVERLAPPED/POPUP/CHILD 視用途)

4.5 CreateDialog vs CreateWindow (第 3 次迭代補充)

CreateDialog(hInst, MAKEINTRESOURCE(IDD_DIALOG), hWndParent, DlgProc);
差異:
1. 對話框模板資源 (DLGTEMPLATE) 定義佈局、控件位置/樣式/ID
2. 系統自動建立對話框視窗、載入模板建立子控件
3. 內部仍有窗口類別 (系統預定義 #32770)
4. 訊息處理:DlgProc 回調函數 (非 WindowProc),支援預設鍵盤導航 (Tab/Enter/Esc)

5. 訊息分類

訊息來源:
├─ 系統產生 (硬體中斷 → WM_KEYDOWN, WM_MOUSEMOVE, WM_TIMER, WM_PAINT...)
└─ API 產生 (PostMessage/SendMessage → 自定義訊息 WM_USER+, WM_APP+)

每個訊息必須發送給特定視窗 (hWnd)
訊息佇列屬於 Thread,唯有 Thread 能接收/處理訊息

總結

Win32 API 領域模型核心三大支柱:

  1. Kernel 物件體系:Process/Thread/File/同步物件,提供執行環境與資源管理
  2. User 物件體系:視窗樹 (Desktop→Top-level→Child)、訊息佇列/訊息分發、窗口類別/風格/程序
  3. GDI 物件體系:DC 容器組合 7 種繪圖物件,支援螢幕/列印/記憶體/資訊 4 種 DC

理解「中斷→訊息→佇列→Thread→WindowProc」完整鏈路,以及視窗風格的本質分類 (CHILD vs OVERLAPPED/POPUP),是掌握 MFC 封裝邏輯 (CWnd::CreateEx, 訊息映射, 命令路由) 的必要前提。

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