訊息映射機制
// .h
class CMyView : public CView {
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
DECLARE_MESSAGE_MAP()
};
// .cpp
BEGIN_MESSAGE_MAP(CMyView, CView)
ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()
void CMyView::OnLButtonDown(UINT nFlags, CPoint point) {
// 點擊座標在 point
}
ClassWizard 維護 //{{AFX_MSG ...}} 註釋區塊,**手動編輯映射需在區塊外**。
文檔-視圖架構下的繪圖邏輯
OnDraw 根據**視圖狀態**繪圖;
- 用戶操作 → 改變狀態 (文檔資料) →
Invalidate → 觸發 OnDraw 重繪;
- 多視圖共享同一文檔,狀態集中於文檔物件,避免全域變數衝突。
無效區優化重繪
InvalidateRect(&rect, TRUE):標記矩形無效,TRUE = 擦除背景;
OnDraw 內呼叫 pDC->GetClipBox(&rectClip) 取得實際裁剪區,**僅繪製與 rectClip 相交的物件**;
- 視窗縮放/遮蔽恢復同樣觸發
WM_PAINT → OnDraw。
幾何測試與座標轉換
PtInRect(&rect, pt) / PtInRegion(rgn, pt);
GetClientRect(&rect) 取得客戶區;
SelectStockObject 選入預設筆/刷/字型;
- 建構函數成員初始化列表:
: m_rect(0,0,200,200), m_color(GRAY_BRUSH) {}。
MFC vs SDK 視窗程序架構
| SDK | MFC |
註冊 WNDCLASS + 視窗程序指標 | 統一視窗類 + 統一視窗程序 AfxWndProc |
CreateWindow 綁定類名 | 句柄映射表 HWND → CWnd* |
視窗程序 switch(msg) 分派 | 運行時類 + 靜態訊息映射表 → 成員函數 |
映射模式完整對照
| 模式 | 邏輯單位 | X 向 | Y 向 | 用途 |
MM_TEXT | 1 像素 | 右增 | 下增 | 裝置座標、位圖操作 |
MM_HIENGLISH | 0.001 inch | 右增 | **上增** | 高精度英制 |
MM_HIMETRIC | 0.01 mm | 右增 | **上增** | 高精度公制 |
MM_LOENGLISH | 0.01 inch | 右增 | **上增** | 低精度英制 |
MM_LOMETRIC | 0.1 mm | 右增 | **上增** | 低精度公制 |
MM_TWIPS | 1/1440 inch | 右增 | **上增** | 排版單位 (1 twip = 1/20 pt) |
**注意**:除 MM_TEXT 外,Y 軸方向與螢幕座標**相反** (符合笛卡兒習慣)。
座標轉換 API
SetViewportOrg(x,y) / GetViewportOrg():視口原點 (裝置座標);
SetWindowOrg(x,y) / GetWindowOrg():視窗原點 (邏輯座標);
DPtoLP(&pt) / LPtoDP(&pt):裝置↔邏輯單點轉換;
DPtoLP(&rect) / LPtoDP(&rect):矩形轉換。
捲動視圖 CScrollView 要點
- 繼承
CScrollView,呼叫 SetScrollSizes(MM_TEXT, sizeTotal) 設定總大小;
OnDraw 直接用邏輯座標繪圖,框架自動處理捲動偏移;
OnPrepareDC 可調整捲動參數;
- 捲動條訊息 (
WM_HSCROLL/WM_VSCROLL) 由基類處理,無需手動映射。
- 上一篇文章: VC++ 技術內幕筆記第 5 章:GDI、色彩與字體繪圖基礎
- 下一篇文章: VC++ 技術內幕筆記第 1-2 章:Windows 應用程式架構與 MFC 文檔-視圖框架
Copyright ©
程式碼之家 All Rights Reserved