1

With a class derived from 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);
    }

What is the most efficient way of painting the window contents with a WTL ScrollWindow?

The CScrollImpl WM_PAINT doesn't pass the CPaintDC to the derived class OnPaint, which has the PAINTSTRUCT m_ps member with the update RECT rcPaint member.

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;
}

So I've handled the WM_PAINT message and the best I've achieved so far is BitBlt the whole _MemDC when scrolled, but during an unscrolled redraw to only BitBlt the invalidated rectangle.

UPDATE:

Sometimes rcPaint is larger than the rectangle of the MemDc so the increase in efficiency is negligible and buggy.

Jan S
  • 408
  • 6
  • 15

1 Answers1

1

Is it really the most efficient or not, however note that WTL Samples include Samples\BmpView project which features CScrollWindowImpl use in CBitmapView class, which displays a visible part of a [supposedly large] image. Specifically, it overrides background erase and paint handlers and demostrates how to do BitBlt for the requested for painting part only.

Roman R.
  • 68,205
  • 6
  • 94
  • 158
  • That sample does a BitBlt of the whole image even when it is larger than the scrolled view. Even though the OS will clip it, it would make more sense not to BitBlt outside of the update rect from the application point of view. – Jan S Mar 24 '17 at 17:19
  • You are correct, the sample blits it completely. If this code - `CBitmapView::DoPaint` for the record - was updated to blit only visible part, the sample would have been improved and would feature more efficient use of `CScrollWindowImpl`... – Roman R. Mar 24 '17 at 17:56