首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

VC6 實作 GDI+ 雙重緩衝:解決大圖拖曳閃爍與效能問題

     編輯:關於VC++

前言

GDI+ 原生支援 JPEG/PNG 等格式,但在 VC6 專案中直接於 OnDraw 讀取檔案繪圖,拖曳捲軸時會頻繁觸發重繪導致嚴重閃爍與效能低落。本文分享雙重緩衝實作技巧:「資料讀取與繪圖分離,離屏繪圖一次完成,再貼回螢幕」,並展示關鍵程式碼片段。

錯誤示範:OnDraw 讀檔繪圖

// 錯誤寫法:每次 OnDraw 都讀檔、解碼、繪圖
void CMyView::OnDraw(CDC* pDC)
{
    CString path = m_pDoc->GetImagePath();
    Image img(path);           // 重複解碼 JPEG
    Graphics g(pDC->m_hDC);
    g.DrawImage(&img, 0, 0);   // 直接畫到螢幕 DC
}

後果:捲軸拖動產生 WM_PAINT → 呼叫 OnDraw → 重複讀檔/解碼 → CPU 飆高、畫面閃爍。

正確架構:Doc/View + 雙重緩衝

1. 文件類別管理影像資料

class CMyDoc : public CDocument
{
public:
    CString m_strMapPath, m_strMapName; // 影像路徑與檔名
    int m_nMapWidth, m_nMapHeight;      // 影像尺寸
    // ...
};

2. 視圖類別持有記憶體 DC 與位圖

class CMyView : public CScrollView
{
    CDC m_memDC;
    CBitmap m_memBitmap;
    CBitmap* m_pOldBitmap;
    // ...
};

3. 影像切換時:更新記憶體位圖(非 OnDraw)

void CMyView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
    CMyDoc* pDoc = GetDocument();
    if (!pDoc) return;

    // 1. 選入記憶體位圖
    m_pOldBitmap = m_memDC.SelectObject(&m_memBitmap);
    // 2. 清背景
    m_memDC.FillSolidRect(0, 0, 2000, 2000, RGB(100,100,100));

    // 3. GDI+ 讀檔並畫到記憶體 DC
    CString fullPath = pDoc->m_strMapPath + pDoc->m_strMapName;
    USES_CONVERSION;
    LPWSTR wPath = A2W(fullPath);
    Image img(wPath);                    // 只在影像改變時解碼一次
    pDoc->m_nMapWidth  = img.GetWidth();
    pDoc->m_nMapHeight = img.GetHeight();

    Graphics g(m_memDC.GetSafeHdc());
    g.DrawImage(&img, 0, 0, img.GetWidth(), img.GetHeight());

    // 4. 還原 DC
    m_memDC.SelectObject(m_pOldBitmap);

    // 5. 更新捲軸範圍並要求重繪
    SetScrollSizes(MM_TEXT, CSize(pDoc->m_nMapWidth, pDoc->m_nMapHeight));
    Invalidate(); // 觸發 OnDraw
}

4. OnDraw 僅負責 BitBlt 貼圖

void CMyView::OnDraw(CDC* pDC)
{
    CMyDoc* pDoc = GetDocument();
    if (!pDoc) return;

    // 僅將記憶體位圖貼到螢幕,極快且無閃爍
    pDC->BitBlt(0, 0, pDoc->m_nMapWidth, pDoc->m_nMapHeight, &m_memDC, 0, 0, SRCCOPY);
}

效果展示

GDI+ 雙重緩衝效果圖

關鍵優勢總結

指標傳統 OnDraw 讀檔雙重緩衝架構
重繪觸發時機每次 WM_PAINT 讀檔解碼僅影像切換時解碼一次
捲軸拖曳流暢度嚴重卡頓、閃爍極順滑,純 BitBlt
CPU 佔用高(重複解碼)低(單次解碼)
記憶體管理臨時物件頻繁建構/解構固定記憶體 DC/位圖複用

結語

核心原則:「耗時操作(讀檔、解碼、複雜繪圖)放在 OnUpdate/資料變更時單次執行,OnDraw 只做極輕量的 BitBlt/Blit」。此模式不限於 GDI+,適用於所有大型位圖、向量圖、複雜場景渲染的 VC/MFC 專案。

原始碼下載:https://www.vckbase.com/code/downcode.asp?id=3116

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