A customer enabled
the WS_
EX_
COMPOSITED
extended window style
in order to solve a flickering problem with their application.
That worked great,
but they found that it had an unwanted side effect:
when the user grabs
the scroll bar and starts scrolling up and down the document,
the UI does not update smoothly.
The customer hoped for some tips on how they could get
the no-flicker benefit of
WS_
EX_
COMPOSITED
without incurring the sluggish-UI penalty.
One of my colleagues explained:
The WS_
EX_
COMPOSITED
extended style enables double-buffering on the window.
This means that the control renders into an off-screen
buffer,
and only when rendering is complete is the result
copied to the screen.
This avoids flicker because only a completely-drawn
control is put on the screen;
you never see the control in a partially-drawn state.
The thing is, in order for this to work, the system needs to know when rendering is complete. Otherwise it doesn't know when it's time to copy the back-buffer to the screen.
The rule is that the system assumes that you're done
rendering when you release the DC.
(Or when you call EndPaint
, which is
the moral equivalent of releasing the DC.)
But there are some programs which acquire a DC and never release it. They just draw into it whenever they feel like drawing. In that case, the system has a fail-safe timeout and copies the back-buffer to the screen after 100ms, and again every 100ms thereafter.
If you're getting slugging UI updates with
the WS_
EX_
COMPOSITED
extended window style,
check that you're properly releasing your device
contexts as soon as you're ready for them to be
presented.
Don't acquire a DC and just hang onto it for convenience.
If you do that, then the system doesn't know when you're
finished drawing,
and it will copy from the back-buffer to the screen
at 10 frames per second,
which will feel sluggish.