5

INTRODUCTION AND RELEVANT INFORMATION:

I have a complex painting to implement in my main window’s WM_PAINT handler.

I have submitted a picture bellow to illustrate it:

enter image description here

Main window has static controls, instead of buttons, which have style SS_NOTIFY.

When user clicks on them, certain actions occur in program.

The following picture shows where static controls in the main window are:

enter image description here

Map on the orange panel is an EMF file ,top left and right logos are PNG files, and other pictures are bitmaps.

In order to implement this task, I have decided to draw the entire picture in WM_PAINT, and to put invisible static controls over the images on the picture that correspond them.

Therefore, I only return NULL_BRUSH in WM_CTLCOLORSTATIC handler like this:

case WM_CTLCOLORSTATIC:
    return (LRESULT)( (HBRUSH)GetStockObject(NULL_BRUSH) );

I work on Windows XP, using MS Visual Studio C++ 2008 Express Edition and pure Win32 API.

One note: since Express edition of VS doesn't have resource editor, resource file and resource header were created using ResEdit from here: http://www.resedit.net/.

PROBLEM:

When I resize my window, static controls slightly flicker.

MY EFFORTS TO SOLVE THE PROBLEM:

I have handled WM_ERASEBKGND (returned (LRESULT)1), and I have excluded styles CS_VREDRAW and CS_HREDRAW from my window class-therefore flickering should not be caused because of this.

My window doesn’t have WS_CLIPCHILDREN style.

EDIT: In response to the comment bellow, I explain why my window doesn't have this style set:

The problem is that part of the desktop picture is seen where static controls are.

I have implemented double buffering for both handlers, in order to avoid flickering.

I have used the tool GDIView, downloaded from here: http://www.nirsoft.net/utils/gdi_handles.html to track down GDI leaks.

Each time I resize my window, GDIView shows +4 in column for regions, which means that I leak regions.

I can’t figure out how is this possible, since I do not use API’s that manipulate with regions.

To illustrate exactly what I am facing with, I have made a demo application , with thorough comments: http://www.filedropper.com/geotermistgrafika

I believe that this is more efficient way, then posting code since it will consume too much space.

QUESTION:

How can I modify code in demo project to get rid of flickering?

Is my approach wrong, and if it is, what is the right one?

Thank you. Regards.

AlwaysLearningNewStuff
  • 2,939
  • 3
  • 31
  • 84
  • While you say that your window doesn't have the `WS_CLIPCHILDREN` style you're not providing a rationale. Why does it not have this style set? – IInspectable Dec 03 '13 at 22:11
  • If I add that style, then parts of the desktop picture are shown where static controls are. – AlwaysLearningNewStuff Dec 03 '13 at 22:13
  • When you resize your window, do you move or resize the static controls? If you do, does Windows automatically move the static control's content? This would account for the flicker. See [WM_NCCALCSIZE](http://msdn.microsoft.com/en-us/library/windows/desktop/ms632634%28v=vs.85%29.aspx). (I would look at your demo code but I'm not going to sign up for some random website just to see it.) – arx Dec 04 '13 at 01:17
  • I use `SetWindowPos` API to move the controls in `WM_SIZE` handler. As for download, there is no need to sign up, download is free, and is at the bottom of the page ( I have checked everything ). I would highly appreciate if you could look at my demo. Thank you. Regards. – AlwaysLearningNewStuff Dec 04 '13 at 10:16
  • I also don't enable Javascript on random sites so I still haven't looked at your code. Anyway, I've posted a solution below. – arx Dec 05 '13 at 00:12

1 Answers1

5

When the main window is resized the WM_SIZE handler moves the static child windows.

When a child window is moved, Windows automatically copies the client area of the child control from the old location to the new location.

The main window will then repaint itself in the WM_PAINT handler.

In other words, when the window is resized all the static controls move to their new position and then the rest of the window is repainted. This lack of synchronization appears as flicker.

You can avoid this by passing the SWP_NOCOPYBITS flag to SetWindowPos.

arx
  • 16,686
  • 2
  • 44
  • 61
  • 1
    Performance is greatly improved. Still, flickering occurs when I resize window from left to right, and it also happens when I resize it from top to bottom. If I resize from right to left/ bottom to top the following effects occur, respectively: right/bottom edge seems to "lag behind" in redrawing, comparing to the other parts of the window. **This effect happens even if I remove static controls.** This is the only thing left for me to solve, before I accept your answer. For now, I have upvoted it. Can you help me with the remaining problems I am facing? Thank you. Regards. – AlwaysLearningNewStuff Dec 05 '13 at 11:16
  • I've answered your question about static controls. This is a new question. Anyway, I seem to recall that Windows XP had a bug in its theme support (which was new at the time), which caused the problem you describe resizing windows. Try creating the default win32 app in VS Express. I think you'll find it has the same problem, but it will work OK on other versions of Windows (either earlier or later). Turning off themes may also make the problem go away. I don't have a copy of XP to hand to try it myself and my memory is hazy so give it a go yourself. – arx Dec 05 '13 at 14:37
  • 1
    All right, I will listen to your advice and try all this without Visual Styles. Also, I will test this on Windows 7. I will ask a new question for the remaining problems I currently face. Thanks again for everything, I have already upvoted your solution. Best regards. – AlwaysLearningNewStuff Dec 05 '13 at 15:27