Windows系统桌面层级背景绘图仅单次生效需重登问题求助
问题描述
按照公开的WorkerW窗口创建方案,调用ProgMan在桌面图标下层创建WorkerW窗口,首次运行时可以正常向该窗口绘图,但停止程序后再次运行就无法成功绘图。
所谓“无法绘图”指无任何报错提示,调试后发现相关数值均无变化:wallpaper_hwnd变量指向的地址不变,所有SDL函数也没有返回错误值。
该问题在Windows 10和Windows 11系统、不同显卡驱动环境下均可复现,目前仅能通过注销后重新登录解决,实用性极低。
另有一个可供排查的参考现象:程序退出后背景会立即恢复为原系统壁纸/配色。
复现代码
#define WIN32_LEAN_AND_MEAN #include <windows.h> #include <shellapi.h> // 根据SDL安装配置不同,也可引入<SDL.h> #include <SDL2/SDL.h> BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) { HWND ShellHandle = FindWindowEx(hwnd, NULL, "SHELLDLL_DefView", NULL); HWND *ret = (HWND *) lParam; if (ShellHandle) { *ret = FindWindowEx(NULL, hwnd, "WorkerW", NULL); } return true; } int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int ShowCmd) { // 获取ProgMan窗口 HWND progman = FindWindow("ProgMan", NULL); // 向ProgMan发送消息生成WorkerW SendMessageTimeout(progman, 0x052C, 0, 0, SMTO_NORMAL, 1000, nullptr); // 找到生成的WorkerW窗口 HWND wallpaper_hwnd = nullptr; EnumWindows(EnumWindowsProc, (LPARAM) &wallpaper_hwnd); // 初始化SDL2 SDL_Init(SDL_INIT_VIDEO); // 从WorkerW窗口创建SDL窗口 SDL_Window* sdl_window = SDL_CreateWindowFrom((void*)wallpaper_hwnd); // 从SDL窗口创建渲染器 SDL_Renderer* renderer = SDL_CreateRenderer(sdl_window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); // 测试清空窗口 SDL_RenderClear(renderer); SDL_RenderPresent(renderer); // 休眠1秒确保效果可见 Sleep(1000); // 资源清理 SDL_DestroyRenderer(renderer); SDL_DestroyWindow(sdl_window); SDL_Quit(); // 测试发现调用该行也无法解决问题 // DestroyWindow(wallpaper_hwnd); return 0; }
已验证的临时解决方法
- 启用WinTab功能可恢复绘图,但该方案不够理想。
内容的提问来源于stack exchange,提问作者Bob Willett
相关产品推荐
相关产品推荐

