# Window with background image (resize problems)

This topic is 3005 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi,

I've been trying to figure this one out for a while now and I just don't know what else I can try.

I have a window in which I am loading a background image with gdiplus.

Problem 1:

The first thing you notice when you resize the window is that the image repaint can't follow the window border, so you can briefly see the window background (in this case, it's black).

Is there any way to fix this?

Problem 2:

The image is being redrawn after a resize event. However, The previously visible area is not included in the update region, which results on what it looks like a stack of images of different sizes.

This can be fixed by handling WM_SIZE and calling InvalidateRect( hWnd, NULL, FALSE ); or by handling WM_NCCALCSIZE and returning WVR_REDRAW.

I wonder if there's any better way to do it.

Problem 3:

Whenever I maximize the window, I don't really see a nice and smooth transition. After taking a closer look at the problem, I noticed that a "shadow" of the original window (including the non-client area) is being kept there until it is maximized and receives a WM_PAINT message that covers it up.

This screenshot might help understanding what I'm trying to explain (it was taken after the window was maximized, but before being repainted):

http://img341.imageshack.us/img341/8401/wnd.png

I hope someone can give me a hand with this, thanks in advance.

Here's my code (I've removed most of the original code because the problems I mentioned can be reproduced with this one):

#include <windows.h>#include <stdio.h>#include <gdiplus.h>#pragma comment( lib, "gdiplus.lib" )using namespace Gdiplus;char m_szAppName[] = "AppName";HINSTANCE m_hInstance;int m_iScreenWidth, m_iScreenHeight;HWND m_hMainWnd;void OnPaint( HDC hDC ){    RECT rcClient;    GetClientRect( m_hMainWnd, &rcClient );    Graphics graphics( hDC );    Image image( L"background.bmp" );    graphics.DrawImage( &image, 0, 0, rcClient.right, rcClient.bottom );}LRESULT CALLBACK MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ){    switch( uMsg )    {    case WM_CREATE:        {            break;        }    case WM_DESTROY:        {            PostQuitMessage( 0 );            break;        }    case WM_PAINT:        {            PAINTSTRUCT ps;            HDC hDC = BeginPaint( hWnd, &ps );            OnPaint( hDC );            EndPaint( hWnd, &ps );            break;        }    case WM_ERASEBKGND:        {            return 1;        }    default:        return DefWindowProc( hWnd, uMsg, wParam, lParam );    }    return 0;}int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ){    HANDLE hMutex = CreateMutex( NULL, FALSE, m_szAppName );    if ( !hMutex || GetLastError() == ERROR_ALREADY_EXISTS )    {        return 0;    }    m_hInstance = hInstance;    GdiplusStartupInput gdiplusStartupInput;    ULONG_PTR           gdiplusToken;    GdiplusStartup( &gdiplusToken, &gdiplusStartupInput, NULL );    WNDCLASSEX wcex;    wcex.cbSize        = sizeof( WNDCLASSEX );    wcex.style         = CS_DBLCLKS;    wcex.lpfnWndProc   = MainWndProc;    wcex.cbClsExtra    = 0;    wcex.cbWndExtra    = 0;    wcex.hInstance     = hInstance;    wcex.hIcon         = LoadIcon( NULL, IDI_APPLICATION );    wcex.hCursor       = LoadCursor( NULL, IDC_ARROW );    wcex.hbrBackground = ( HBRUSH )GetStockObject( BLACK_BRUSH );    wcex.lpszMenuName  = NULL;    wcex.lpszClassName = m_szAppName;    wcex.hIconSm       = NULL;    if ( !RegisterClassEx( &wcex ) )    {        return 0;    }    m_iScreenWidth = GetSystemMetrics( SM_CXSCREEN );    m_iScreenHeight = GetSystemMetrics( SM_CYSCREEN );    HWND hWnd = CreateWindow(        m_szAppName,        m_szAppName,        WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,        ( m_iScreenWidth / 2 ) - ( 800 / 2 ), ( m_iScreenHeight / 2 ) - ( 600 / 2 ),        800, 600,        NULL,        NULL,        hInstance,        NULL    );    if ( !hWnd )    {        return 0;    }    m_hMainWnd = hWnd;    ShowWindow( hWnd, nCmdShow );    UpdateWindow( hWnd );    MSG msg;    while ( GetMessage( &msg, NULL, 0, 0 ) )    {        TranslateMessage( &msg );        DispatchMessage( &msg );    }    GdiplusShutdown( gdiplusToken );    return msg.wParam;}

##### Share on other sites
What is your rationale for not correctly handling WM_ERASEBKGND? As the documentation indicates this is pretty important to handle properly if you want your window repainted nicely. I suspect at least a good chunk of your problems can be tied to that alone.

As for your Problem #2 - invalidating the window in WM_SIZE is probably the best option.

##### Share on other sites
Quote:
 Original post by ApochPiQWhat is your rationale for not correctly handling WM_ERASEBKGND? As the documentation indicates this is pretty important to handle properly if you want your window repainted nicely. I suspect at least a good chunk of your problems can be tied to that alone.As for your Problem #2 - invalidating the window in WM_SIZE is probably the best option.

Thanks for replying. Just before you posted, I solved problem 3 by checking for a flag on WM_ERASEBKGND.

As for problem 1, gdiplus might just be too slow to redraw in time for the image to fit the resized window, that's my guess atleast.

Regards

##### Share on other sites
I missed this the first time - is there a reason for loading the image over and over again in every WM_PAINT handling? Can you just cache the image instead? That should get you a bit of extra draw speed.

##### Share on other sites
Quote:
 Original post by ApochPiQI missed this the first time - is there a reason for loading the image over and over again in every WM_PAINT handling? Can you just cache the image instead? That should get you a bit of extra draw speed.

Well, I've done that before, it seemed obvious to me that file i/o would be responsible for the slowness of redraws. At the time, I didn't notice any visible difference though. And now I am unable to make it work so I can't test again.

Once again, thanks.

##### Share on other sites
Besides the important things ApochPiQ mentioned, you should also resize the cached image whenever the window is resized, so whenever the cached image is used to paint the background, it's just blitted rather than stretched blitted. This will also allow you to take advantage of the rcPaint "dirty rectangle" given to you inside of the PAINTSTRUCT, so that you don't need to repaint the entire window. That won't help on resizing, but it will for other things.

That rcPaint rect, btw, also defines the clipping rect that BegPaint setup for the hDC it returned to you. That may be the cause of the "stepped" effect you see when you resize the window from small to large.

##### Share on other sites
Quote:
 Original post by redllarBesides the important things ApochPiQ mentioned, you should also resize the cached image whenever the window is resized, so whenever the cached image is used to paint the background, it's just blitted rather than stretched blitted. This will also allow you to take advantage of the rcPaint "dirty rectangle" given to you inside of the PAINTSTRUCT, so that you don't need to repaint the entire window. That won't help on resizing, but it will for other things.That rcPaint rect, btw, also defines the clipping rect that BegPaint setup for the hDC it returned to you. That may be the cause of the "stepped" effect you see when you resize the window from small to large.

Thanks for replying. Yes, I was already doing that in my original code. I'm comparing client area rects and using a background DC from which I BitBlt whenever I don't need to resize the image.

For now, I've solved my problems by making sure that the area that needs to be repainted is black. When the user is done resizing, it repaints the whole client area with a resized background image.

If anyone's interested, I can post the new code.

Regards

1. 1
2. 2
3. 3
Rutin
16
4. 4
5. 5

• 10
• 10
• 14
• 10
• 25
• ### Forum Statistics

• Total Topics
632647
• Total Posts
3007640
• ### Who's Online (See full list)

There are no registered users currently online

×