在桌面背景上绘制作为壁纸替换(Windows / C#)

时间:2009-11-05 21:32:59

标签: c# windows desktop wallpaper

我正在尝试制作一个需要在桌面上绘制的应用程序,在图标后面,以便它可以替换桌面墙纸。我已经找到了一些解决方案,但大多数都不能很好地工作(很多闪烁)。一个解决方案seems to be what I'm looking for,但我真的没有。我主要使用更高级别的图形库或Windows窗体,以及一些C ++,但仅在非Windows平台上完成C#应用程序。

如果有人可以为我“翻译”它或为我提供替代解决方案,我们将不胜感激!

5 个答案:

答案 0 :(得分:7)

我从来没有找到我想要的解决方案,但这里有最好的(只有?)替代方案:

  • 绘制到“SysListView32”窗口(ProgMan - > SHELLDLL_DefView - > SysListView32)。这将在桌面图标后面绘制,但在使用动画时会闪烁。如何:Link(你必须在.NET中使用互操作)。

  • 使用DirectDraw叠加层。您将桌面颜色设置为某种模糊的颜色,具有该颜色的所有内容将替换为覆盖图上的内容。这在我的问题和VLC壁纸模式的示例中使用。但是,这与Aero不兼容。如何:Link(我想你可以在.NET中使用Managed DirectX?)。

答案 1 :(得分:1)

您可以在VLC媒体播放器代码中找到灵感。有一个wallpaper mode能够满足您的需求。

答案 2 :(得分:0)

是的,使用互操作,请参阅this主题。

答案 3 :(得分:0)

顺便看到这个问题,我做了部分解决问题(但不是以某种方式我可以提供任何有用的代码)来制作一些很酷的游戏,虽然可能没有你想要的应用程序:

  • 将桌面背景恢复正常并拍摄桌面的屏幕截图
  • 将桌面背景设置为黑色并拍摄桌面的屏幕截图
  • 将桌面背景设置为白色并拍摄桌面的屏幕截图
  • 将黑白版本组合在一起制作蒙版,并将第一个屏幕截图组合为不同透明度的叠加设置像素值。

现在,在您的表单上按顺序绘制以下内容:

  1. 绘制第一个屏幕截图
  2. 绘制表单
  3. 绘制您创建的桌面叠加层
  4. 这是我为全屏幕形式所做的,但我认为可以很容易地适应非全屏幕形式。基本上你已经重新创建了桌面,但有能力做任何事情,包括一些很酷的游戏。任何应用程序的绘制速度和性能都令人满意,但桌面交互性是个问题...... :(这是使用原理的坦克游戏的照片,除了我将背景设置为白色并使所有白色背景都透明!

    My Tanks Game

答案 4 :(得分:0)

我知道这是一个很晚的答案,但我最近亲自调查了一下,如果其他用户遇到相同的问题,这可能会对他们有所帮助。

注意:此答案适用于C ++,但也许可以帮助您在C#中完成同样的操作

正如上面评论中提到的,我跟随This guide了解我将如何绘制 ON 窗口。

使用以下两种方法:

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中创建一个窗口。

由于涉及大量代码,因此我将链接my solution on github。这样可以在桌面图标后面画很多星星(尽管我相信可以改善)。