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 link to the picture that describes it, bellow:
http://pbrd.co/1hGVPPu[
^]
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 ):
http://pbrd.co/1hGW6C3[
^]
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);
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);
Graphics graphics( MemDC );
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)
{
n_height = static_cast<UINT>( ( (double)n_width ) / ratio );
}
else
n_width = static_cast<UINT>(n_height * ratio);
graphics.SetSmoothingMode( SmoothingModeHighQuality );
graphics.SetInterpolationMode( InterpolationModeHighQualityBicubic );
graphics.DrawImage( &image, r.left + 5, r.top + 10, n_width, n_height );
Graphics graphics1( MemDC );
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)
{
n_height = static_cast<UINT>( ( (double)n_width ) / ratio );
}
else
n_width = static_cast<UINT>(n_height * ratio);
graphics1.SetSmoothingMode( SmoothingModeHighQuality );
graphics1.SetInterpolationMode( InterpolationModeHighQualityBicubic );
graphics1.DrawImage( &image1, r.right - r.left - 90, r.top + 10,
n_width, n_height );
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.