徹底搞懂第 1 課每行代碼的含義,理解 CChartWnd 如何接管消息循環、Attach/Detach 內部原理、靜態變量生命週期管理。
#include "Chart.h"
#ifdef _DEBUG
#pragma comment(lib, "PlotDll_d.lib") // Debug 版帶檢查、符號
#else
#pragma comment(lib, "PlotDll.lib") // Release 版優化
#endif
Chart.h:唯一對外頭文件,定義 CChartWnd、CChart 等包裝類。static CChartWnd chartWndWndProc 每次收到消息都會被調用,局部變量會隨棧幀銷毀。static 使其存儲在全局數據區,生命週期 = 進程壽命。CChartWnd 類體系CChart (核心繪圖引擎,模板實現)
↑ 封裝隱藏模板細節
CChartWnd (繼承自 CChart,同時是窗口類)
↑ 自動處理 WM_PAINT/WM_MOUSEMOVE/WM_LBUTTONDOWN 等消息
用戶主窗口
CChart* 指針,轉發繪圖調用。WindowProc,攔截繪圖相關消息,其餘轉發給原 WndProc。WM_CREATE 中的初始化流程chartWnd.Attach(hWnd, kTypeXY); // 關鍵步驟
chartWnd.GetChart()->AddPoint2D(...); // 7 個點
chartWnd.GetChart()->SetTitle(...);
Attach(hWnd, kTypeXY):
SetWindowLongPtr(hWnd, GWLP_WNDPROC, ...) 替換窗口過程。kTypeXY 為 enum ChartType { kTypeXY, kTypeContourLine, ... }。WM_PAINT、滑鼠消息先由 chartWnd 處理,再鏈式傳遞。WM_DESTROY 中的清理chartWnd.Detach();
SetWindowLongPtr(hWnd, GWLP_WNDPROC, oldProc)。WM_PAINT 代碼向導生成的 DrawText 繪製 "Hello World" 文字,因消息已被 chartWnd 攔截處理,保留也無害但屬多餘。
CChartWnd 內部維護 WNDPROC oldProc,實現責任鏈模式。| 錯誤 | 後果 | 修正 |
|---|---|---|
漏 static | 圖表閃爍、數據丟失、崩潰 | 加 static 或改全局/成員 |
漏 Detach | 退出崩潰、GDI 泄漏 | 在 WM_DESTROY 必調用 |
| Debug 配 Release 庫 | 斷言失效、堆損壞 | 用 #ifdef _DEBUG 區分 |
第 3 課:零代碼實現專業級交互——高亮、選擇、屬性編輯、右鍵菜單,全部內建!