Search code examples
c++winapiwindowdraw

C++ Win32 Background Image


I have looked at some background drawing tutorials but I still can't draw my background; it's always white. My resources are already in the project. I have tried a few other ways by using paint instead but it still would not draw the background image.

#include <windows.h>
#include <commctrl.h>
#include "resource.h"
HINSTANCE hInst;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
HWND hProgress, hWndBottom;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    hInst = hInstance;
    MSG msg          = {0};
    WNDCLASS wc      = {0}; 
    wc.lpfnWndProc   = WndProc;
    wc.hInstance     = hInstance;
    wc.hbrBackground = CreatePatternBrush( LoadBitmap( hInstance, MAKEINTRESOURCE(IDB_BG) ));//(HBRUSH)(COLOR_BACKGROUND);
    wc.lpszClassName = "Test";
    if( !RegisterClass(&wc) )
        return 1;
    if( !CreateWindow(wc.lpszClassName,
               "Tests",
               WS_POPUPWINDOW|WS_VISIBLE, //WS_OVERLAPPEDWINDOW|WS_VISIBLE
               1,1,200,250,0,0,hInstance,NULL))
        return 2;
    while( GetMessage( &msg, NULL, 0, 0 ) > 0 )
        DispatchMessage( &msg );
    return 0;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    //Make TopMost
    ::SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
    INITCOMMONCONTROLSEX InitCtrlEx;
    InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
    InitCtrlEx.dwICC  = ICC_PROGRESS_CLASS;

    SendMessage(hProgress, PBM_SETRANGE, 0, MAKELPARAM(0, 100)); 
    switch(message)
    {
    case WM_CREATE:
        {
             hProgress = CreateWindowEx(0, PROGRESS_CLASS, NULL,
                   WS_CHILD | WS_VISIBLE | PBS_SMOOTH,
                   10, 190, 170, 10,
                   hWnd, NULL, hInst, NULL);
        }
        break;

    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}  

Solution

  • If you're going to draw a bitmap for your background, you do not just set the background brush to the handle of your bitmap.

    Instead, you set the background brush to NULL, and handle the WM_ERASEBKGND message. You respond to it by drawing your bitmap (e.g., with BitBlt or StretchBlt), then you return TRUE (or any other non-zero value) to tell DefWindowProc that the background has been erased, so it shouldn't try to erase it.

    Note that if you're doing this in an MDI program, you need to do this in the MDI client window. With MDI, you have a parent window, a client window, and some number of MDI child windows. What looks like the background of the main window is really occupied by the MDI client window, so that's where you need to draw in your background.