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.
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.