views:

339

answers:

2

I have an application with three MDI windows, all of them showing OpenGL content. On XP, everything works fine. But on Vista/Win7 the mdi child windows don't refresh properly.

After startup, all windows show their content properly. But when I change the focus from one mdi window to the next, those two windows are cleared (i.e., they only show white, no content). I have no idea why the windows get cleared, they don't receive any WM_* message when that happens, and of course don't receive a WM_PAINT message either.

When resizing those windows, I correctly get the WM_PAINT message (after WM_SIZE) and redraw the content, but then the window gets cleared too, which results in a strange flicker while resizing. After resizing stopped, the window stays cleared (white) until I manually force a refresh.

This happens independently of Aero enabled or disabled.

Any idea why this happens?

+2  A: 

I'm surprised it works on XP. In my (limited) experience dabbling with OpenGL, WM_PAINT is not always the best place to redraw OpenGL scenes. Most likely the content is getting wiped out at the driver level. You can check for this by seeing what happens when one of your MDI windows happens to span two monitors connected to two different video cards.

Try the following:

  1. Reinitialize your OpenGL contexts after WM_SIZE occurs.
  2. Draw on-demand instead of in WM_PAINT. In your handler for WM_PAINT, do nothing. Use a timer or some other mechanism to periodically trigger updates of your displays.
  3. Flicker is usually caused by interference via WM_ERASEBKGND. If you haven't already, intercept WM_ERASEBKGND and do nothing in the regions where you are displaying OpenGL content.
  4. Use the CS_OWNDC window style on any windows hosting OpenGL content so that the HDC doesn't change per-message/per-call during the lifetimes of your MDI windows.

Other rarer causes of interference that might apply (since you are using MDI windows)

  1. WM_NCPAINT and other related Non-Client drawing messages- you can workaround these by moving your OpenGL content to a child window with no border, inside the MDI windows.
  2. Incorrect/Incompatible default features for OpenGL on your video card that explicitly require overlays or implicitly use them (frequent cause of issues in overlapping contexts). Unfortunately, diagnosing this out of my realm of knowledge, but some testing may shed some additional light here.
meklarian
Thanks for all the hints. I'll try these as soon as I'm back at the office.
Stefan
np. Also, you might get better responses from people who have deeper OpenGL experience by posting a snippet of your context initialization code.
meklarian
A: 

Did you have any joy with this? I'm experiencing the same. Making sure the WM_ERASEBKGND is handled cures the flicker on resize but not the content disappearing when they lose focus. Even if you don't use a WM_PAINT solution you see the flicker when it shouldn't be being erased in the first place. This only happens when it is an MDI window, if I change it to a regular one it works fine.

Chris