tags:

views:

196

answers:

2

I'm drawing directly to the screen using BitBlt and GetDC(IntPtr.Zero). Is there some way to call Refresh or Invalidate on the whole screen when I'm done, so that I don't leave big chunks of paint everywhere (digitally speaking)?

Update: when you draw directly to the screen like I'm doing, whatever you draw remains there until the window underneath it repaints itself (and in so doing, repaints the portion of the screen it's covering).

The problem is that some portions of the windows desktop don't repaint themselves for long periods. For example, if I draw over top of the task bar, the actual tasks repaint themselves fairly quickly (along with the Start button etc.), but the taskbar itself retains what I've drawn for as long as a couple of minutes.

If my app had a window that covered the entire screen, I would just call Invalidate() on that form which would cause it to repaint itself and thus the entire screen. What I need is some way of calling Invalidate or Refresh on the whole screen itself.

+1  A: 

The "screen" is made up of a set of windows that are parented to the Desktop Window. I would imagine that you could simply invalidate the desktop window, though you may need to recurse through its child windows (the top-level application windows) and invalidate them too. (There may also be issues with mutliple monitors, but this should give you a starting point)

See GetDesktopWindow().

Alternatively, create a form that covers the entire screen, and use transparent drawing. Then simply close the fom when you're done.

Jason Williams
He'll probably just have to enumerate all windows and invalidate the cleanup rectangle in each one of them. Broadcasting `WM_PAINT` also worked back in the old days, but it's almost certainly overkill.
vladr
+1  A: 

InvalidateRect(NULL, NULL, TRUE) should invalidate and redraw all windows. Though it will be expensive operation.

An alternative approach would be to remember where you've drawn and try to enumerate any windows in that rectangle and invalidate only them.

You can also try creating a transparent window over the area you've painted when you want to invalidate the windows there. Note that you want to do alpha-blended layered window, not an WS_TRANSPARENT window. If you do it with 99% transparency, the DWM should repaint all the windows below it once it's destroyed. Of course, this could lead to barely perceptible flicker over the target region due to the alphablending of the window before you destroy it.

Franci Penov
Looks like this will work. It won't matter that it's expensive, since I'll only be calling this once. What I'm doing is rendering a full-screen animation, so I only need to repaint the entire screen once, after the animation is completed.
MusiGenesis