Static controls slightly flicker when main window

2019-04-29 15:39发布

问题:

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:

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:

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.

回答1:

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.