WTL滚动窗口高效绘画



使用派生自 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 滚动窗口绘制窗口内容的最有效方法是什么?

CScrollImpl WM_PAINT 不会将 CPaintDC 传递给派生类 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项目,该项目CScrollWindowImpl类中使用的功能CBitmapView,它显示[据说很大]图像的可见部分。具体来说,它覆盖背景擦除和绘画处理程序,并演示如何仅对请求的绘画部分执行BitBlt

最新更新