在C ++中在Windows 10墙纸上绘图

时间:2019-05-14 14:18:19

标签: c++ windows winapi desktop-wallpaper

是否可以使用C ++处理Windows墙纸(图标后面)以便进行绘制? 这样就可以使活动桌面(在Windows XP之后停产)等效,墙纸引擎等效或任何其他类似工具。 (在我的情况下,对墙纸的温度和资源使用情况进行监控)。

注意:GetDesktopWindow()返回的句柄将返回桌面图标级别的窗口,而不是其后的窗口。

similar questions的解决方案不适用于我。 具体来说,我尝试了VLC媒体播放器的wallpaper mode代码。

关键代码是:

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;
 }

但是它不会在墙纸上绘制。

1 个答案:

答案 0 :(得分:4)

draw behind desktop icons C#页的内容仅供参考。本文解释了该解决方案背后的理论,该理论适用于无论使用哪种编程语言。

长话短说,更改墙纸时您在Windows 10上看到的平滑淡入淡出的动画是通过创建一个完全符合您要求的新窗口并在图标下绘制来实现的。该窗口实现了新墙纸的淡入效果,由程序管理器创建。

在提到的文章中,您可以与C#实现一起查看每个步骤的说明。在这里,我将编写一个等效的C ++,保留源代码中的注释。

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
    {
    HWND p = FindWindowEx(hwnd, NULL, L"SHELLDLL_DefView", NULL);
    HWND* ret = (HWND*)lParam;

    if (p)
        {
        // Gets the WorkerW Window after the current one.
        *ret = FindWindowEx(NULL, hwnd, L"WorkerW", NULL);
        }
    return true;
    }

HWND get_wallpaper_window()
    {
    // Fetch the Progman window
    HWND progman = FindWindow(L"ProgMan", NULL);
    // Send 0x052C to Progman. This message directs Progman to spawn a 
    // WorkerW behind the desktop icons. If it is already there, nothing 
    // happens.
    SendMessageTimeout(progman, 0x052C, 0, 0, SMTO_NORMAL, 1000, nullptr);
    // We enumerate all Windows, until we find one, that has the SHELLDLL_DefView 
    // as a child. 
    // If we found that window, we take its next sibling and assign it to workerw.
    HWND wallpaper_hwnd = nullptr;
    EnumWindows(EnumWindowsProc, (LPARAM)&wallpaper_hwnd);
    // Return the handle you're looking for.
    return wallpaper_hwnd;
    }

根据您的编码偏好,可以用reinterpret_cast替换类C的转换。


本文未提及的一个笔记: 由于更改墙纸时会生成一个新的WorkerW窗口以实现褪色效果,因此,如果用户在程序正在主动绘制并刷新WorkerW实例的同时尝试更改墙纸,则用户设置的背景将放置在您的绘图之上,请开始逐渐消失,直到达到100%的不透明度,最后被破坏,从而使WorkerW仍在运行。