我正在尝试制作一个应用程序,需要在桌面上绘图,在图标后面绘制,以便看起来替换了桌面壁纸。我已经找到了一些解决方案,但大多数都效果不佳(闪烁很多)。其中一个解决方案似乎是我想要的,但我真的不明白。我通常使用较高级别的图形库或仅使用Windows Forms来编写C#应用程序,还有一些C++,但仅限于非Windows平台。
如果有人能为我“翻译”一下或提供另一种解决方案,那将不胜感激!
我知道这是一个相当晚的答案,但最近我自己也研究了一下,如果其他用户有同样的问题,这可能会对他们有所帮助。
注意:这个答案是针对C++的,但也许它可以帮助你在C#中做同样的事情。
正如上面的评论中提到的,我遵循了这个指南来理解我将如何能够在Windows壁纸窗口上绘制图形。
通过使用以下两种方法:
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) {
HWND p = FindWindowEx(hwnd, NULL, "SHELLDLL_DefView", NULL);
HWND* ret = (HWND*)lParam;
if (p)
{
// Gets the WorkerW Window after the current one.
*ret = FindWindowEx(NULL, hwnd, "WorkerW", NULL);
}
return true;
}
HWND get_wallpaper_window() {
// Fetch the Progman window
HWND progman = FindWindow("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;
}
我能够检索到Windows句柄。
由于我只熟悉SDL,这是我找到的唯一解决方案,但我相信任何允许你基于另一个窗口创建/修改窗口的方法都可以起作用。
window = SDL_CreateWindowFrom((void*)get_wallpaper_window());
上述代码允许我使用get_wallpaper_window()
方法检索到的HWND创建一个SDL窗口。
由于涉及大量代码,我将链接我的github解决方案。这可以在您的桌面图标后面绘制很多星星(尽管我认为它可以改进)。
现在,在您的表单上按顺序绘制以下内容:
这就是我为全屏表单所做的事情,但是很容易适应非全屏表单。本质上,您已经重新创建了桌面,但具有执行任何操作的能力,包括一些很酷的游戏。绘制速度和性能对于任何应用程序都是令人满意的,但桌面交互性是一个问题... :( 这是使用该原理的坦克游戏的图片,除了我将背景设置为白色并使所有白色背景也透明!