INTRODUCTION AND RELEVANT INFORMATION:
FORMER TITTLE OF THE QUESTION:
Window produces flicker-like ( slow repainting-like ) effect when resized
I have a complex painting to implement in my main window’s WM_PAINT
handler.
I have submitted a picture bellow.
Logo’s marked with 1 and 2, are drawn using GDI+
. Logo marked as 1, is metafile
, and logo marked with 2 is PNG
.
If I leave out drawing of the second logo, my window doesn’t flicker, yet if I add the drawing of the second logo in my WM_PAINT
, the following effect, illustrated with the picture below, occurs ( this is just a sketch made in Paint, but hopefully it will clear things up ):
It seems as if the repainting is slow.
IMPORTANT NOTE: This effect happens on child windows, the background is painted properly.
Just in case it matters, the information about child windows:
All 5 child windows are static controls.
Static controls with blue gradient are painted with double buffering, using GDI
, in WM_CTLCOLORSTATIC
.
Orange static control is subclassed
, and is ownerdrawn
.
IMPORTANT NOTE: I must say that this is my first time using GDI+
.
In my WM_PAINT
handler, I have made compatible memory DC, required for double buffering, like this:
HDC hdc = BeginPaint( hwnd, &ps), hdcMemImg, MemDC;
MemDC = CreateCompatibleDC(hdc); // back buffer.
Compatible bitmap has dimensions of main window’s client area.
As I’ve said, everything seems to work fine, since I use GDI
and double buffering to paint/draw.
When I need to paint the logo’s marked with 1 and 2, I do it with this code:
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
Image image(L".\\resources\\BG.emf"), image1(L".\\resources\\RGF.png");
switch(msg)
{
case WM_ERASEBKGND:
return (LRESULT)1;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint( hwnd, &ps), hdcMemImg, MemDC;
MemDC = CreateCompatibleDC(hdc); // back buffer.
// CreateCompatibleBitmap and other usual stuff
/******************** left logo *******************/
Graphics graphics( MemDC );
//============= aspect ratio ================//
UINT o_height = image.GetHeight(),
o_width = image.GetWidth();
INT n_width = 80;
INT n_height = 100;
double ratio = ( (double)o_width ) / ( (double)o_height );
if (o_width > o_height)
{
// Resize down by width
n_height = static_cast<UINT>( ( (double)n_width ) / ratio );
}
else
n_width = static_cast<UINT>(n_height * ratio);
//========== ensure high graphic quality ======================//
graphics.SetSmoothingMode( SmoothingModeHighQuality );
graphics.SetInterpolationMode( InterpolationModeHighQualityBicubic );
graphics.DrawImage( &image, r.left + 5, r.top + 10, n_width, n_height );
/******************** right logo *******************/
Graphics graphics1( MemDC );
//============= aspect ratio ================//
o_height = image1.GetHeight(),
o_width = image1.GetWidth();
n_width = 90;
n_height = 100;
ratio = ( (double)o_width ) / ( (double)o_height );
if (o_width > o_height)
{
// Resize down by width
n_height = static_cast<UINT>( ( (double)n_width ) / ratio );
}
else
n_width = static_cast<UINT>(n_height * ratio);
//=========== ensure high graphic quality ============//
graphics1.SetSmoothingMode( SmoothingModeHighQuality );
graphics1.SetInterpolationMode( InterpolationModeHighQualityBicubic );
graphics1.DrawImage( &image1, r.right - r.left - 90, r.top + 10, n_width, n_height );
// Then do BitBlt of MeDC to hdc, and clean it up
If additional code snippets are required, ask and I will edit my post, but for now, they are omitted to keep the post short and concise.
I work on Windows XP, using MS Visual Studio C++ and pure Win32 API.
My CPU is single core ( 2,67 GHz ), and I have 768 MB of RAM.
IMPORTANT UPDATE:
When I turn on Task Manager
, I can see that the memory consumption of my application sky rockets.
It never drops, it always grows, especially when I resize the window.
Detailed description of my efforts to solve this can be found bellow.
I have decided to take the advice of the more experienced and better developers, and will provide link to the demo project.
One note: since Express edition of VS has no resource editor, resource file and resource header were created using ResEdit
from here http://www.resedit.net/.
Here is the link to the demo project ( all the necessary comments and explanations are in the projects comments ):http://www.uploadmb.com/dw.php?id=1382012579.
MY EFFORTS TO SOLVE PROBLEM:
Browsing through the Internet, SO archive, CodeProject, and CodeGuru, I was unable to see the problem-it seems ( and I believe too ), that the principles of double buffering in GDI+
and GDI
are the same.
IMPORTANT UPDATE:
I have downloaded VLD
from http://vld.codeplex.com/, followed their instructions, but VLD
didn't detect any memory leaks.
Also, I have made a copy of the project and have deleted static controls, leaving only the window's background to ease my debugging.
Memory consumption described above still happens.
It seems to stop only if I don't draw logos.
QUESTION:
Since this is my first time using GDI+
, is there something that I’m missing, in view of releasing/deleting some GDI+
object or something similar ( all the GDI+
code for drawing in WM_PAINT
is submitted )?
Again, I believe that my other painting code works well, but I will post it if required.
UPDATE:
Regarding the updates provided above, what should I do to fix the problem of excessive memory consumption described above?
Can someone review small demo project provided above, and try to give me useful advice?
Thank you.
Regards.