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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 11:30:00