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
相关产品推荐
相关产品推荐

