TabControl 切換頁面時會觸發 WM_PAINT 重繪,若直接在 OnPaint 中用 MoveTo/LineTo 即時繪圖,舊幀內容會被背景擦除覆蓋,導致曲線消失。
// 類別成員
CBitmap m_memBitmap;
CDC m_memDC;
CRect m_drawRect; // 繪圖區域
// OnInitDialog 初始化
void CMyDlg::OnInitDialog() {
CDialogEx::OnInitDialog();
GetDlgItem(IDC_STATIC_DRAW)->GetWindowRect(&m_drawRect);
ScreenToClient(&m_drawRect);
CClientDC dc(this);
m_memDC.CreateCompatibleDC(&dc);
m_memBitmap.CreateCompatibleBitmap(&dc, m_drawRect.Width(), m_drawRect.Height());
m_memDC.SelectObject(&m_memBitmap);
// 初始清白
m_memDC.FillSolidRect(&m_drawRect, RGB(255,255,255));
DrawCurveToMemDC(); // 畫好第一幀
}
// 所有繪圖邏輯集中於此,只畫到 m_memDC
void CMyDlg::DrawCurveToMemDC() {
CPen pen(PS_SOLID, 2, RGB(0,0,255));
CPen* oldPen = m_memDC.SelectObject(&pen);
m_memDC.MoveTo(10, 100);
m_memDC.LineTo(200, 50);
// ... 更多 LineTo
m_memDC.SelectObject(oldPen);
}
// OnPaint 僅做 BitBlt
void CMyDlg::OnPaint() {
CPaintDC dc(this);
dc.BitBlt(m_drawRect.left, m_drawRect.top,
m_drawRect.Width(), m_drawRect.Height(),
&m_memDC, 0, 0, SRCCOPY);
}
// 需要更新曲線時(如新數據到達)
void CMyDlg::OnNewDataPoint(double value) {
DrawCurveToMemDC(); // 重畫記憶體 DC
InvalidateRect(&m_drawRect, FALSE); // 觸發 WM_PAINT
}
OnPaint 統一 BitBlt,畫面永不丟失。CBitmap,合成時依序 BitBlt。void CMyDlg::OnDestroy() {
m_memDC.SelectObject(m_memDC.GetCurrentBitmap()); // 還原預設位圖
m_memBitmap.DeleteObject();
m_memDC.DeleteDC();
CDialogEx::OnDestroy();
}