Click here to Skip to main content
14,329,594 members

Double buffering malfunctions (updated with small demo source code )

AlwaysLearningNewStuff asked:

Open original thread
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:
http://pbrd.co/18fNYYp[^]

Main window has static controls, instead of buttons, which have style SS_NOTIFY.
When user clicks on them, certain actions occur in program, which are irrelevant for now.

The following picture shows where static controls in the main window are:
http://pbrd.co/18fOkya[^]

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

Visual Styles are enabled via #pragma directive. I also use GDI+ along with the GDI.

Project was created as empty project and I have coded everything from “scratch”.

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

In order to keep my code clean and simple, I have made functions that implement the above, so my WM_PAINT handler can be as small as possible.

Gradient brushes were made with the usage of GradientFill(...) API.

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/.[^]

UPDATE #1( updated on December 17th, 2013 ):

In order to make things easier for those trying to help, here is the single source file with minimal code that illustrates the problem: http://pastebin.com/BeAVHViC[^]

PROBLEM:

In order to avoid flickering, I have used double buffering, which I have learned from Paul Watt’s articles, Charles Petzold’s Programming Windows 5th edition and Forger’s WIN32 tutorial.

Theoretically speaking, everything is OK, and my code compiles without any errors.

I have pasted the code here:
http://pastebin.com/zSYT1i8L[^]

My English is not good enough to accurately describe the problems that I face ( all I can say is that edges of the main window and static control's redraw “slow” and they flicker ) so I have created a demo application that demonstrates them:
http://www.filedropper.com/geotermistgrafika[^]

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 because part of the desktop picture is seen where static controls are.

In my WM_SIZE handler I have :
1. Repositioned static controls using SetWindowPos(...) API and reduced flickering by adding the SWP_NOCOPYBITS flag.

2. Invalidated the entire window with the InvalidateRect( hWnd, NULL, FALSE ), so this API does not send WM_ERASEBKGND when invalidating ( 3rd parameter is FALSE ), but even if I try with TRUE the effect is the same.

I have implemented double buffering for WM_PAINT handler like in the examples found in the above books/articles/tutorials ( by doing everything in the memory DC and do BitBlt(...) on screen DC in order to avoid flickering ).

I didn’t handle WM_SIZING, nor WM_WINDOWPOSCHANGING, or WM_MOVING message.

I have used the tool GDIView ( http://www.nirsoft.net/utils/gdi_handles.html[^] ) to track down GDI leaks.
Each time I resize/maximize my window, GDIView shows +4 in column for regions, which should mean that I leak regions but I can’t figure out how is this possible, since I do not use API’s that manipulate with regions, and have double checked everything.

In my opinion everything should be fine and maybe this is irrelevant, but I just thought to mention it, in case it is important.

If I add WS_EX_COMPOSITED style to the main window, the performance does not improve.

I have tried to find online example that would help me to solve my problem but all the tutorials are simple and do not cover this type of complex pictures.

IMPORTANT NOTE:

Before improving this question, I got two solutions suggested, one of them advising me to do as much as I can in WM_ERASEBKGND.

After leaving my WM_PAINT handler empty and calling onPaint function in WM_ERASEBKGND with the device context obtained with GetDC(..) API, the flickering disappeared, but during the resizing, redrawing of the window was “spiky” and the problem with the edges of the main window was not solved.
Still, this is much better improvement than the original code.

UPDATE ( December, 17th 2013 ):

After removing the call drawImages( hdc, MemDC, r ); from onPaint, the flickering of the edges occurs again.

It seems less, and the number of regions GDIView detects as leaked is reduced by one.

QUESTION:

How to get rid of the problems demonstrated in my demo application, provided above?

I hereby thank anyone who invests its time and efforts to try to help me.

Best regards.
Tags: C++, Win32, GDI, GDI+

Preview



When answering a question please:
  1. Read the question carefully.
  2. Understand that English isn't everyone's first language so be lenient of bad spelling and grammar.
  3. If a question is poorly phrased then either ask for clarification, ignore it, or edit the question and fix the problem. Insults are not welcome.
  4. Don't tell someone to read the manual. Chances are they have and don't get it. Provide an answer or move on to the next question.
Let's work to help developers, not make them feel stupid.
Please note that all posts will be submitted under the The Code Project Open License (CPOL).




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100