Is there a way to get an handle to Windows's wallpaper (behind icons) in C++ in order to draw on it? That would allow to make an active desktop (discontinued after Windows XP) equivalent, a Wallpaper Engine equivalent, or any other similar tool. (Temperature and resources usage monitoring on the wallpaper in my case).
Note: the handle returned by GetDesktopWindow() returns the window at desktop icons level, not behind it.
Solutions from similar questions aren't working for me. Specifically i tried VLC media player's wallpaper mode code.
Key code is:
hwnd = FindWindow( _T("Progman"), NULL );
if( hwnd ) hwnd = FindWindowEx( hwnd, NULL, _T("SHELLDLL_DefView"), NULL );
if( hwnd ) hwnd = FindWindowEx( hwnd, NULL, _T("SysListView32"), NULL );
if( !hwnd )
{
msg_Warn( p_vout, "couldn't find \"SysListView32\" window, "
"wallpaper mode not supported" );
return;
}
But it will not draw on the wallpaper.
Credits to this draw behind desktop icons C# page as reference. The article explains the theory behind the solution, which applies regardless of the programming language being used.
Long story short, the smooth fading animation you see on Windows 10 when changing wallpaper is achieved by creating a new window that does exactly what you're asking for, drawing under the icons. That window achieves the fade-in effect for the new wallpaper, and is created by the Program Manager.
In the mentioned article you can see together with C# implementation an explanation of every step. Here i'll write a C++ equivalent keeping comments from the source.
The C-like casts can be replaced with
reinterpret_casts, according to your coding preferences.One note that isn't mentioned in the article: Since when changing wallpaper a new WorkerW window is generated to achieve the fading effect, if the user tries to change wallpaper while your program is actively drawing and refreshing your instance of WorkerW, the user set background will be placed on top of your drawing, start fading in until it reaches 100% opacity, and lastly be destroyed, leaving your WorkerW still running.