You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinApi中窗口背景图片无法设置的问题求助

问题:WinAPI窗口无法显示背景图片

我正在学习用C语言给WinAPI窗口设置背景图片,以下是我的代码:

#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;
}

然而,尽管.exe文件所在目录下存在test.bmp位图文件,背景图片仍无法正常显示。我还尝试了网上的不同位图以及自行用画图工具制作的位图,问题依旧。


问题分析与修复

你的代码存在几个关键问题,导致背景图片无法正常显示:

  • 窗口过程未绑定:注册窗口类时,wc.lpfnWndProc = DefWindowProc; 会让系统使用默认窗口过程,你自定义的WindowProcedure完全没被调用,WM_CREATE消息触发的图片加载代码根本没执行。修复:将该行改为 wc.lpfnWndProc = WindowProcedure;

  • 窗口过程返回值缺失:WindowProcedure处理完WM_CREATE后没有返回值,会引发未定义行为。需在函数末尾添加return 0;,确保所有分支都有合法返回值。

  • 静态控件尺寸固定:你创建的静态控件尺寸是300x300,仅占窗口一部分区域。若要铺满窗口,可在WM_CREATE时获取客户区尺寸设置控件大小,或在WM_SIZE消息中动态调整。

  • 缺少加载错误检查:未验证LoadImage的返回值,无法确认图片是否成功加载。可添加错误提示代码排查问题。

  • 资源泄漏风险:加载的位图资源需在窗口销毁时释放,避免内存泄漏。

修复后的完整代码

#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:
        // 获取窗口客户区尺寸,设置静态控件铺满窗口
        RECT client_rect;
        GetClientRect(hwnd, &client_rect);
        int client_w = client_rect.right - client_rect.left;
        int client_h = client_rect.bottom - client_rect.top;
        
        hbackground = CreateWindow("STATIC", "background", SS_BITMAP | WS_CHILD | WS_VISIBLE, 
                                   0, 0, client_w, client_h, hwnd,
                                   NULL, NULL, NULL);
        hbackground_image = (HBITMAP)LoadImage(NULL, background_name, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
        if (!hbackground_image) {
            MessageBox(NULL, "Failed to load bitmap", "Error", MB_OK | MB_ICONERROR);
        }
        SendMessage(hbackground, STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hbackground_image);
        break;
    case WM_SIZE:
        // 窗口大小改变时,同步调整静态控件尺寸
        RECT new_client_rect;
        GetClientRect(hwnd, &new_client_rect);
        SetWindowPos(hbackground, NULL, 0, 0, 
                     new_client_rect.right - new_client_rect.left, 
                     new_client_rect.bottom - new_client_rect.top,
                     SWP_NOZORDER);
        break;
    case WM_DESTROY:
        // 释放位图资源
        if (hbackground_image) {
            DeleteObject(hbackground_image);
        }
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hwnd, msg, wp, lp);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WindowProcedure; // 绑定自定义窗口过程
    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);
    if (!hwnd)
    {
        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;
}

内容的提问来源于stack exchange,提问作者work work

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 10:50:37