Home > Software design >  Background image fails to get set for a window in WinApi
Background image fails to get set for a window in WinApi

Time:11-14

I am learning to how to set a background image for a window in C. Here is my code:

#include <stdio.h>
#include <windows.h>

char* window_name = "Window";
char* window_title = "Window Title";
char* background_name = "test.bmp";
int window_width = 600;
int window_height = 400;

HBITMAP hbackground_image;
WNDCLASSEX wc;
HWND hwnd, hbackground;
MSG msg;

LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
    switch (msg)
    {
    case WM_CREATE:
        hbackground = CreateWindow("STATIC", "background", SS_BITMAP | WS_CHILD | WS_VISIBLE, 0, 0, 300, 300, hwnd,
                                   NULL, NULL, NULL);
        hbackground_image = (HBITMAP)LoadImage(NULL, background_name, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
        SendMessage(hbackground, STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hbackground_image);
        break;
    default:
        return DefWindowProc(hwnd, msg, wp, lp);
    }
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = DefWindowProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW   1);
    wc.lpszMenuName = NULL;
    wc.hIconSm = LoadIcon(hInstance, IDI_APPLICATION);
    wc.lpszClassName = window_name;

    if (!RegisterClassEx(&wc))
    {
        MessageBox(NULL, "Windows registration failure", NULL, MB_RETRYCANCEL);
        return 1;
    }
    hwnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, window_name, window_title, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
                          CW_USEDEFAULT, window_width, window_height, NULL, NULL, hInstance, NULL);
    // hwnd = CreateWindow("test", "test title", WS_OVERLAPPED | WS_VISIBLE, 100, 100, 500, 500, NULL, NULL, NULL, NULL); // This fails
    if (!hwnd) // If fails
    {
        MessageBox(NULL, "Window creation failed :(", NULL, MB_RETRYCANCEL);
        return 2;
    }
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    while (GetMessage(&msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}

However, the background image doesn't get set even though there is a bitmap in the same folder as the .exe. I also tried different bitmaps from the internet, and one I made in paint. Any help would be appreciated.

CodePudding user response:

This line is wrong:

wc.lpfnWndProc = DefWindowProc;

You are not seeing your background image because you are not using your WindowProcedure() with the window class, and thus it is never called to load/display the bitmap.

That line needs to be this instead:

wc.lpfnWndProc = WindowProcedure;

Also, when processing WM_CREATE, you are not return'ing any value, so the result is indeterminate, which is undefined behavior. You need to return 0; for that message:

LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
    switch (msg)
    {
    case WM_CREATE:
        ...
        return 0;
    }
    return DefWindowProc(hwnd, msg, wp, lp);
}
  • Related