在 C++ 中绘制 Windows 10 张壁纸
Draw on Windows 10 wallpaper in C++
有没有办法在 C++ 中获取 Windows 的墙纸(在图标后面)的句柄以便在上面绘图?
这将允许制作活动桌面(在 Windows XP 后停产)等价物、Wallpaper Engine 等价物或任何其他类似工具。 (在我的案例中,墙纸上的温度和资源使用情况监控)。
注意:GetDesktopWindow()
returns window 返回的句柄在桌面图标级别,而不是在它后面。
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;
}
但是不会画在墙纸上
感谢此 draw behind desktop icons C# 页面作为参考。本文解释了解决方案背后的理论,无论使用何种编程语言,该理论都适用。
长话短说,您在 Windows 10 上看到的平滑褪色动画是通过创建一个新的 window 来实现的,它完全符合您的要求,在图标下绘图. window实现了新壁纸的fade-in效果,由程序管理器创建。
在提到的文章中,您可以看到与 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;
}
根据您的编码偏好,C-like 转换可以替换为 reinterpret_cast
。
一篇文章中没有提到的注释:
由于在更改壁纸时会生成一个新的 WorkerW window 来实现淡入淡出效果,如果用户在您的程序正在主动绘制和刷新您的 WorkerW 实例时尝试更改壁纸,则用户设置的背景将放置在你的绘图,开始淡入直到它达到 100% 的不透明度,最后被销毁,留下你的 WorkerW 仍然 运行.
有没有办法在 C++ 中获取 Windows 的墙纸(在图标后面)的句柄以便在上面绘图? 这将允许制作活动桌面(在 Windows XP 后停产)等价物、Wallpaper Engine 等价物或任何其他类似工具。 (在我的案例中,墙纸上的温度和资源使用情况监控)。
注意:GetDesktopWindow()
returns window 返回的句柄在桌面图标级别,而不是在它后面。
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;
}
但是不会画在墙纸上
感谢此 draw behind desktop icons C# 页面作为参考。本文解释了解决方案背后的理论,无论使用何种编程语言,该理论都适用。
长话短说,您在 Windows 10 上看到的平滑褪色动画是通过创建一个新的 window 来实现的,它完全符合您的要求,在图标下绘图. window实现了新壁纸的fade-in效果,由程序管理器创建。
在提到的文章中,您可以看到与 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;
}
根据您的编码偏好,C-like 转换可以替换为 reinterpret_cast
。
一篇文章中没有提到的注释: 由于在更改壁纸时会生成一个新的 WorkerW window 来实现淡入淡出效果,如果用户在您的程序正在主动绘制和刷新您的 WorkerW 实例时尝试更改壁纸,则用户设置的背景将放置在你的绘图,开始淡入直到它达到 100% 的不透明度,最后被销毁,留下你的 WorkerW 仍然 运行.