WTL ScrollWindow高效绘画

WTL ScrollWindow efficient painting

使用 class 派生自 CScrollWindowImpl

  void Scroll::DoPaint(CDCHandle hDC)
    {
        if ( _MemDC==NULL)
            return;
        RECT r;

//I'd like to update r with rcPaint from the DC's PAINTSTRUCT here

        hDC.BitBlt(r.left, r.top, r.right-r.left, r.bottom-r.top,
            *_MemDC, r.left, r.top, SRCCOPY);
    }

使用 WTL ScrollWindow 绘制 window 内容的最有效方法是什么?

CScrollImpl WM_PAINT 不会将 CPaintDC 传递给派生的 class OnPaint,它具有 PAINTSTRUCT m_ps 成员和更新的 RECT rcPaint 成员。

LRESULT CScrollImpl::OnPaint(UINT, WPARAM wParam, LPARAM, BOOL&) {
    T* pT = static_cast<T*>(this);
    ATLASSERT(::IsWindow(pT->m_hWnd));
    if(wParam != NULL) { // The HDC is sometimes passed in
        CDCHandle dc = (HDC)wParam;
        dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y);
        pT->DoPaint(dc);
    }
    else {
        CPaintDC dc(pT->m_hWnd);
        dc.SetViewportOrg(-m_ptOffset.x, -m_ptOffset.y);
        pT->DoPaint(CDCHandle(dc));
    }
    return 0;
}

所以我已经处理了 WM_PAINT 消息,到目前为止我取得的最好成绩是在滚动时对整个 _MemDC 进行 BitBlt,但在未滚动重绘期间仅对无效矩形进行 BitBlt。

更新:

有时 rcPaint 比 MemDc 的矩形大,因此效率的提高可以忽略不计并且有错误。

它真的是最有效的还是不是最有效的,但是请注意 WTL 示例包括 Samples\BmpView 项目,该项目具有 CScrollWindowImplCBitmapView class 中使用的功能,它显示一个可见的[假定为大] 图像的一部分。具体来说,它会覆盖背景擦除和绘制处理程序,并演示如何仅对请求的绘制部分执行 BitBlt