Avoid Flickering on a dialog that moves its contro

2019-08-03 04:32发布

问题:

I have a popup dialog( CDialog ) that handles WM_CTLCOLOR message to color itself. It is having some controls (like bitmap buttons) that draws themselves using OwnerDraw. It is also having a control that displays an image with size that takes up to 70% of the dialog.

When user re-sizes the dialog, some of the controls in the dialog should be re-positioned (not re-sized). It also involves re-sizing of the image inside the dialog. As the re-sizing of image makes the whole process slow, individual re-positioning of the controls are causing a visual effect of flickering.

I need to get rid of these. One idea is to put the controls as the children of an intermediate dialog that is the child of the original popup dialog. So, when there is a re-size, I can re-position the dialog only instead of moving each controls individually. (Re-position happens only in one direction (x or y), so moving the intermediate dialog should be enough.

As it involves some coding effort, before going this way, I need answers to the following questions:

  • Will this work?
  • If yes, whats the complexity involved in this method?
  • Is there a better way?

Please help!

回答1:

It will probably work, but you should try solutions that don't alter your control hierarchy before, because it has other subtle consequences (focus, tab order, message notifications, etc).

Try one or all of the following:

  • Use BeginDeferWindowPos/DeferWindowPos/EndDeferWindowPos functions to move the children.
  • Set the WS_CLIPCHILDREN style flag in the dialog.
  • Set the WS_EX_LAYERED extended style flag in the dialog.


回答2:

Simple fixes are:

  • creating the slow window last so that it doesn't hold up drawing of the simple controls
  • turning on the WS_EX_COMPOSITED style flag so Windows double-buffers the entire window, including its children. Beware of painting artifacts
  • turning off the WS_CLIPCHILDREN style flag so the holes are not so noticeable. Making the background white would accomplish the same
  • keeping the drawing of slow controls simple between WM_ENTERSIZEMOVE and WM_EXITSIZEMOVE
  • using less controls, burning up an expensive window on a simple string or image is unnecessary