views:

187

answers:

2

I'd like to prevent my window from being updated until I finish receiving data from the server and render it. Can I hook on the WM_PAINT event, or better still call some Win32API method to prevent the window from being updated and unfreeze it later?

More info: In the context of an MMC snapin written in C#, our application suffers from annoying flickering and double sorting behaviour: We use MMC's listViews, but since we subscribe to the sort event. MMC does it's own magic and sorts the page being displayed (and we can't override that), and when we receive a reply from our server we change the listView again. each row change is done sequentially, there's no beginUpdate etc. (AFAIK).

+1  A: 

Normally hooking into WM_PAINT is the way to go, but make sure you also ignore all WM_ERASEBKGND notifcations, otherwise you'll still get flicker, because Windows erases the Windows area for you. (Return non-zero to prevent Windows from doing that)

One other possibility is to use the LockWindowUpdate function, but it has some drawbacks:

  • Only one window can be locked
  • Upon unlock the whole desktop and all sub-windows (i.e. everything) is repainted, resulting in short flash of the whole desktop. (It's worse on XP than on Vista)
DR
+1  A: 

Some controls have BeginUpdate and EndUpdate APIs for this purpose.

If you do something (e.g. hook and ignore paint events) do disable painting, then a way to force a repaint later is to call the Invalidate method.

ChrisW
That might be true in some environments, but AFAIK `Invalidate` just marks the whole window region as "invalid", so the next paint event repaints everything. Invalidate by itself does not force a repaint, it only forces that *when* a repaint is happening, everything is repainted.
DR
Of course, that depends on the framework. In .NET Invalidate also triggers a paint event.
DR
@DR there's also an `Update` method to force an immediate update after invalidate. SFAIK, invoking Update causes a synchrnous paint event, whereas just calling Invalidate results in an asynchronous paint, i.e. a WM_PAINT will be generated when the message queue is empty of any other messages.
ChrisW