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

CChart 入門教程第 2 課:代碼深度解析與核心機制揭秘

     編輯:關於C語言

本課目標

徹底搞懂第 1 課每行代碼的含義,理解 CChartWnd 如何接管消息循環、Attach/Detach 內部原理、靜態變量生命週期管理。

代碼逐段解析

1. 頭文件與導入庫選擇

#include "Chart.h"
#ifdef _DEBUG
#pragma comment(lib, "PlotDll_d.lib") // Debug 版帶檢查、符號
#else
#pragma comment(lib, "PlotDll.lib")   // Release 版優化
#endif
  • Chart.h:唯一對外頭文件,定義 CChartWnd、CChart 等包裝類。
  • 雙庫機制:避免 Debug/Release 混用導致堆損壞、斷言失效。

2. 靜態變量 static CChartWnd chartWnd

  • 為何 static? WndProc 每次收到消息都會被調用,局部變量會隨棧幀銷毀。static 使其存儲在全局數據區,生命週期 = 進程壽命。
  • 替代方案:定義為全局變量或封裝在類成員中(推薦做法)。

3. CChartWnd 類體系

CChart (核心繪圖引擎,模板實現)
    ↑ 封裝隱藏模板細節
CChartWnd (繼承自 CChart,同時是窗口類)
    ↑ 自動處理 WM_PAINT/WM_MOUSEMOVE/WM_LBUTTONDOWN 等消息
用戶主窗口
  • 內部持有 CChart* 指針,轉發繪圖調用。
  • 重寫 WindowProc,攔截繪圖相關消息,其餘轉發給原 WndProc。

4. WM_CREATE 中的初始化流程

chartWnd.Attach(hWnd, kTypeXY); // 關鍵步驟
chartWnd.GetChart()->AddPoint2D(...); // 7 個點
chartWnd.GetChart()->SetTitle(...);
  • Attach(hWnd, kTypeXY):
    1. 子類化主窗口:SetWindowLongPtr(hWnd, GWLP_WNDPROC, ...) 替換窗口過程。
    2. 創建兼容 DC、位圖,初始化繪圖引擎。
    3. kTypeXY 為 enum ChartType { kTypeXY, kTypeContourLine, ... }。
  • 掛靠後,主窗口 WM_PAINT、滑鼠消息先由 chartWnd 處理,再鏈式傳遞。

5. WM_DESTROY 中的清理

chartWnd.Detach();
  • 恢復原窗口過程:SetWindowLongPtr(hWnd, GWLP_WNDPROC, oldProc)。
  • 釋放 GDI 資源(DC、位圖、筆刷、字體)。
  • 若漏調用 → 程序退出時 GDI 泄漏、甚至崩潰。

6. 移除默認 WM_PAINT 代碼

向導生成的 DrawText 繪製 "Hello World" 文字,因消息已被 chartWnd 攔截處理,保留也無害但屬多餘。

進階補充:為什麼要子類化而非繼承?

  • Win32 API 無原生「繼承窗口類」機制;子類化是標準擴展手法。
  • CChartWnd 內部維護 WNDPROC oldProc,實現責任鏈模式。

常見錯誤避坑

錯誤後果修正
漏 static圖表閃爍、數據丟失、崩潰加 static 或改全局/成員
漏 Detach退出崩潰、GDI 泄漏在 WM_DESTROY 必調用
Debug 配 Release 庫斷言失效、堆損壞用 #ifdef _DEBUG 區分

下課預告

第 3 課:零代碼實現專業級交互——高亮、選擇、屬性編輯、右鍵菜單,全部內建!

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