首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

MFC 繪圖擦除上一幀數據的實現技巧

     編輯:程式設計疑難解答

問題背景

在 MFC 應用中,使用 OnDraw 根據採集數據繪製圖表時,每次刷新需要清除上一次的繪圖內容。數據屬於不同列,如何高效實現「擦除舊數據、繪製新數據」?

核心思路:雙緩衝 + 區域重繪

  1. 雙緩衝繪圖:在內存位圖上完成所有繪圖操作,最後一次性 BitBlt 到螢幕 DC,消除閃爍。
  2. 記錄上一幀幾何信息:將上一次繪製的線段、點座標存入容器(如 std::vector)。
  3. 擦除策略:
    • 簡單做法:FillSolidRect 整個客戶區,配合雙緩衝無閃爍。
    • 精細做法:僅對上一幀佔用的矩形區域調用 InvalidateRect,配合 WM_ERASEBKGND 返回 TRUE 禁止默認擦除,在 OnDraw 中先用背景筆刷覆蓋舊區域,再繪製新數據。
  4. 多列數據管理:為每列數據維護獨立的顏色、線型及座標容器,繪圖時遍歷所有列。

關鍵代碼片段

// OnDraw 簡略邏輯
void CMyView::OnDraw(CDC* pDC) {
    // 1. 建立兼容 DC 與位圖(雙緩衝)
    CMemDC memDC(pDC); // MFC 封裝類或自行實現

    // 2. 擦除上一幀區域(若採用精細擦除)
    for (auto& rect : m_prevRects) {
        memDC.FillSolidRect(rect, GetSysColor(COLOR_WINDOW));
    }
    m_prevRects.clear();

    // 3. 繪製所有列數據
    for (auto& series : m_dataSeries) {
        CPen pen(PS_SOLID, 1, series.color);
        CPen* pOld = memDC.SelectObject(&pen);
        // Polyline 等繪圖...
        memDC.SelectObject(pOld);
        // 記錄本幀佔用矩形供下一次擦除
        m_prevRects.push_back(series.GetBoundingRect());
    }
}

參考資源

可參考百度知道相關源碼示例:MFC 繪圖擦除源碼

總結

結合雙緩衝與區域無效化/重繪,即可實現流暢、無閃爍的多列數據動態繪圖與擦除。

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