I'm having an issue where if I get ProgMan
to create a WorkerW
window behind the desktop icons (as described by https://stackoverflow.com/a/56132585/5923516), it allows me to draw to it the first time, but if I stop it and then try and run it again, it fails to draw. By 'fails to draw', I mean that I don't see any errors, but it just doesn't do anything. I've also tried to debug it and none of the effected values change (i.e. the wallpaper_hwnd
variable points to the same place, and none of the SDL functions return error values) I've verified this behaviour on both Windows 10 and 11, both using different video drivers. The only way I've found to fix this is to log out then log back in, which doesn't really help.
Once exited I also noticed that the background instantly changes back to the wallpaper picture/colour. But I don't know if that information is useful.
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <shellapi.h>
// Can also be <SDL.h> depending on the install of SDL
#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) {
// Get the ProgMan Window
HWND progman = FindWindow("ProgMan", NULL);
// Get ProgMan to create a WorkerW
SendMessageTimeout(progman, 0x052C, 0, 0, SMTO_NORMAL, 1000, nullptr);
// Find the WorkerW that was spawned
HWND wallpaper_hwnd = nullptr;
EnumWindows(EnumWindowsProc, (LPARAM) &wallpaper_hwnd);
// Init SDL2
SDL_Init(SDL_INIT_VIDEO);
// Create an SDL Window from this
SDL_Window* sdl_window = SDL_CreateWindowFrom((void*)wallpaper_hwnd);
// Create SDL Renderer from the SDL Window
SDL_Renderer* renderer = SDL_CreateRenderer(sdl_window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
// Clear the window as a test
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
// Sleep for 1 second so that the change is actually visible
Sleep(1000);
// Clean up
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(sdl_window);
SDL_Quit();
// In my testing this doesn't fix it:
// DestroyWindow(wallpaper_hwnd);
return 0;
}
If anyone can work out why I'm getting these issues then I would greatly appreciate it.
EDIT:
After messing around a bit, I've found that wintabbing makes it work again. This still isn't a very good solution, however.