Search code examples
c#.netgdibitblt

How to clean up after myself when drawing directly to the screen


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.


Solution

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