作者:zhoujiamurong | 郵箱:zhoujiamurong@163.com
版權所有,轉載請聯繫作者。
GDI (Graphics Device Interface) 是 Windows 提供的繪圖抽象層。面對顯示器、印表機等不同輸出設備,GDI 通過設備上下文 (DC, Device Context) 屏蔽硬體差異,讓程式碼無需關心具體驅動即可跨設備繪圖——類似 Java 虛擬機屏蔽平台差異。

新增五個菜單項:直線、矩形、圓角矩形、圓、曲線,ID 分別為 ID_DRAW_LINE 等。工具欄同步添加對應按鈕,並啟用停靠功能:
// OnCreateClient 中工具欄升級
UINT toolIDs[] = { 0, ID_DISPLAY_DOWN, ID_DISPLAY_UP, ID_DISPLAY_RIGHT,
ID_DISPLAY_LEFT, 0,
ID_DRAW_LINE, ID_DRAW_RECT, ID_DRAW_ROUND_RECT,
ID_DRAW_CIRCLE, ID_DRAW_CURVE };
m_wndToolBar.CreateEx(this, TBSTYLE_FLAT,
WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
m_wndToolBar.LoadBitmap(IDB_BITMAP1);
m_wndToolBar.SetButtons(toolIDs, 11);
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar, AFX_IDW_DOCKBAR_TOP);
Windows 為了效率,不重繪整個窗口,而是標記無效區域。當區域無效時,系統發送 WM_PAINT,MFC 映射為 ON_WM_PAINT() → OnPaint()。所有繪圖邏輯集中在 OnPaint 中。
class CMainFrame : public CFrameWnd {
// ...
CPoint m_ptStart; // 起始點
CPoint m_ptEnd; // 終止點
CRect m_rectInvalid; // 無效矩形區域
};
void OnLButtonDown(UINT nFlags, CPoint point) {
m_ptStart = point;
}
void OnLButtonUp(UINT nFlags, CPoint point) {
m_ptEnd = point;
// 構建包含兩點的矩形
m_rectInvalid.SetRect(m_ptStart, m_ptEnd);
m_rectInvalid.NormalizeRect(); // 確保 left
void OnPaint() {
CPaintDC dc(this); // 自動 BeginPaint/EndPaint
dc.MoveTo(m_ptStart);
dc.LineTo(m_ptEnd);
}
CPaintDC:專用於 OnPaint 的 DC 類,構造時自動 BeginPaint,析構時 EndPaint,確保繪圖區域正確驗證。InvalidateRect:將矩形加入無效區域隊列,觸發 WM_PAINT。MoveTo/LineTo:GDI 基本繪圖函數,通過 DC 發送給驅動程式。按下滑鼠左鍵拖動釋放,即在釋放處畫出一條直線。這是繪圖程序的雛形,下一節將擴展支持多種圖形與持久化。