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

VC++ 6.0 視圖滾動重繪:在 OnDraw 中根據滾動位置繪製網格/坐標軸

     編輯:程式設計綜合問答

問題:CView 中繪製的網格線、圖形、坐標軸,滾動條滾動後消失。原因:OnDraw 未根據滾動位置計算繪製區域。

核心原理

  • OnDraw(CDC* pDC) 接收的 pDC 已經根據滾動位置設置了 視口原點 (SetViewportOrg)。
  • 所有邏輯座標 (如 MoveTo(100,100)) 會自動映射到正確的屏幕像素。
  • 只需在 OnDraw 中用邏輯座標完整繪製整個文檔內容,系統自動裁剪可見區域。

正確實現步驟

  1. 設置映射模式 (通常 MM_LOENGLISH 或 MM_TEXT) 並設定文檔大小 SetScrollSizes。
  2. OnDraw 中完整繪製:網格、坐標軸、數據曲線全部用邏輯座標畫一次。
  3. 無需手動處理滾動消息,MFC 自動調用 OnDraw 並傳遞已偏移的 DC。

代碼範例:網格 + 滾動視圖

// MyView.h
class CMyView : public CView {
    DECLARE_DYNCREATE(CMyView)
protected:
    CSize m_docSize; // 文檔邏輯大小
public:
    virtual void OnDraw(CDC* pDC);
    virtual void OnInitialUpdate();
};

// MyView.cpp
void CMyView::OnInitialUpdate() {
    CView::OnInitialUpdate();
    m_docSize = CSize(2000, 2000); // 邏輯單位 (0.01mm)
    SetScrollSizes(MM_LOENGLISH, m_docSize);
}

void CMyView::OnDraw(CDC* pDC) {
    // 1. 繪製網格 (每 100 邏輯單位一條線)
    CPen penGrid(PS_DOT, 1, RGB(200,200,200));
    CPen* pOldPen = pDC->SelectObject(&penGrid);
    for (int x = 0; x <= m_docSize.cx; x += 100) {
        pDC->MoveTo(x, 0);
        pDC->LineTo(x, m_docSize.cy);
    }
    for (int y = 0; y <= m_docSize.cy; y += 100) {
        pDC->MoveTo(0, y);
        pDC->LineTo(m_docSize.cx, y);
    }

    // 2. 繪製坐標軸 (紅色粗線)
    CPen penAxis(PS_SOLID, 2, RGB(255,0,0));
    pDC->SelectObject(&penAxis);
    pDC->MoveTo(0, m_docSize.cy/2);
    pDC->LineTo(m_docSize.cx, m_docSize.cy/2); // X軸
    pDC->MoveTo(m_docSize.cx/2, 0);
    pDC->LineTo(m_docSize.cx/2, m_docSize.cy); // Y軸

    pDC->SelectObject(pOldPen);
}

關鍵點

  • SetScrollSizes(MM_LOENGLISH, totalSize) 建立文檔大小與滾動範圍映射。
  • OnDraw 使用邏輯座標 (如 1000 代表 1 英吋),而非設備像素。
  • MFC 自動計算 pDC->GetClipBox() 裁剪不可見部分,無需手動判斷。
  • 若需優化,可在 OnDraw 開頭獲取 CRect clipRect; pDC->GetClipBox(&clipRect); 僅繪製相交對象。

常見錯誤

  • 在 OnHScroll/OnVScroll 中手動 Invalidate() 並試圖計算偏移繪製 → 複雜且易錯。
  • 使用 MM_TEXT (像素模式) 但未自行處理偏移 → 滾動後圖形位置錯亂。

遵循「文檔座標系 + OnDraw 全繪 + MFC 自動裁剪」模式,滾動重繪即可正常工作。

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