更换桌面壁纸/在桌面上绘制

发布于 2024-07-18 07:45:23 字数 487 浏览 9 评论 0原文

我想对我的 Windows 桌面进行一些自定义绘图,以便它看起来可以替换桌面背景(壁纸)。 我的第一次尝试是为 desktopListView 获取一个 DC 并绘制到它:

IntPtr desktopDC = GetWindowDC(desktopListView);
Graphics g = Graphics.FromHwnd(desktopDC); //<-- fails on out of memory error

然后我尝试创建一个 NativeWindow 并通过将本机窗口的句柄分配给桌面来捕获 WM_PAINT 消息并做我自己的绘图,但我无法在桌面上看到任何消息。

理想情况下,我想在 WPF 中执行此操作,而不是在 Windows 窗体中执行此操作。 有任何线索如何创建一个可以绘制的 WPF 窗口,该窗口位于桌面图标下方但位于壁纸顶部,以便它忽略任何鼠标消息并且桌面继续正常工作吗?

I'd like to do some custom drawing to my windows desktop such that it appears to replace the desktop background (wallpaper). My first try was to get a DC for desktopListView and draw to it:

IntPtr desktopDC = GetWindowDC(desktopListView);
Graphics g = Graphics.FromHwnd(desktopDC); //<-- fails on out of memory error

I then tried to create a NativeWindow and capture the WM_PAINT message by assigning the native window's handle to the desktop and do my own drawing, but I was unable to see any messages to the desktop.

Ideally I'd like to do this in WPF and not windows forms at all. Any clue how to create a WPF window that I can draw to that sits beneath the desktop icons but on top of the wallpaper such that it ignores any mouse messages and the desktop continues to work normally?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

鸠书 2024-07-25 07:45:23

如果您获得桌面的窗口句柄,则可以创建一个新窗口并将您自己的自定义窗口添加为该窗口的子窗口。 将其放在列表视图后面可能会给您带来所需的结果,尽管我不能 100% 确定透明度的效果如何。

找到一些代码 - 如果您不需要处理改变形状的多个屏幕,那么您需要的大部分内容都在第一部分中。

    public void SetDesktopWindows()
    {
        Thread.Sleep(0);
        while (this.Count < Screen.AllScreens.Length)
        {
            OrangeGuava.Desktop.DesktopWindow.DesktopControl dtc = new OrangeGuava.Desktop.DesktopWindow.DesktopControl();
            User32.SetParent(dtc.Handle, User32.FindWindow("ProgMan", null));
            this.Add(dtc);

        }

        int minx = 0;
        int miny = 0;

        foreach (Screen screen in Screen.AllScreens)
        {               
            if (screen.Bounds.Left < minx) minx = screen.Bounds.Left;
            if (screen.Bounds.Top < miny) miny = screen.Bounds.Top;
        }

        for (int i = Screen.AllScreens.Length; i < Count; i++)
        {
            OrangeGuava.Desktop.DesktopWindow.DesktopControl dtc = (OrangeGuava.Desktop.DesktopWindow.DesktopControl)this[i];
            dtc.Hide();
        }

        for (int i = 0; i < Screen.AllScreens.Length; i++)
        {
            OrangeGuava.Desktop.DesktopWindow.DesktopControl dtc = (OrangeGuava.Desktop.DesktopWindow.DesktopControl)this[i];
            dtc.DeviceId = i.ToString();


            Rectangle r = Screen.AllScreens[i].WorkingArea;
            r.X -= minx;
            r.Y -= miny;



            dtc.SetBounds(r.X, r.Y, r.Width, r.Height);

            dtc.displaySettingsChanged(null, null);


        }

    }

If you get the window handle of the desktop, you can create a new window and add your own custom window as a child of that. Putting it behind the list view may give you the result you need, though I'm not 100% sure how well the transparency will work.

Found some code - Most of what you need is in the first part if you don't need to deal with multiple screens that change shape.

    public void SetDesktopWindows()
    {
        Thread.Sleep(0);
        while (this.Count < Screen.AllScreens.Length)
        {
            OrangeGuava.Desktop.DesktopWindow.DesktopControl dtc = new OrangeGuava.Desktop.DesktopWindow.DesktopControl();
            User32.SetParent(dtc.Handle, User32.FindWindow("ProgMan", null));
            this.Add(dtc);

        }

        int minx = 0;
        int miny = 0;

        foreach (Screen screen in Screen.AllScreens)
        {               
            if (screen.Bounds.Left < minx) minx = screen.Bounds.Left;
            if (screen.Bounds.Top < miny) miny = screen.Bounds.Top;
        }

        for (int i = Screen.AllScreens.Length; i < Count; i++)
        {
            OrangeGuava.Desktop.DesktopWindow.DesktopControl dtc = (OrangeGuava.Desktop.DesktopWindow.DesktopControl)this[i];
            dtc.Hide();
        }

        for (int i = 0; i < Screen.AllScreens.Length; i++)
        {
            OrangeGuava.Desktop.DesktopWindow.DesktopControl dtc = (OrangeGuava.Desktop.DesktopWindow.DesktopControl)this[i];
            dtc.DeviceId = i.ToString();


            Rectangle r = Screen.AllScreens[i].WorkingArea;
            r.X -= minx;
            r.Y -= miny;



            dtc.SetBounds(r.X, r.Y, r.Width, r.Height);

            dtc.displaySettingsChanged(null, null);


        }

    }
倒数 2024-07-25 07:45:23

我通过设置 WINDOWPOS.hWndInsertAfter = HWND_BOTTOM 让我的窗口响应 WM_WINDOWPOSCHANGING 消息来完成此操作。 这对操作系统说:确保我的窗口位于所有其他窗口的下方,并使其看起来就像您的窗口粘在桌面上一样。

I've done this by having my window respond to the WM_WINDOWPOSCHANGING message by setting WINDOWPOS.hWndInsertAfter = HWND_BOTTOM. This says to the OS: make sure my window is underneath all other windows, and makes it appear as though your window is glued to the desktop.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文