Замена обоев рабочего стола / рисование на рабочем столе - PullRequest
3 голосов
/ 07 мая 2009

Я бы хотел сделать какой-нибудь нестандартный рисунок на рабочем столе Windows, чтобы он заменял фон рабочего стола (обои). Моей первой попыткой было получить DC для desktopListView и нарисовать к нему:

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

Затем я попытался создать NativeWindow и захватить сообщение WM_PAINT, назначив дескриптор собственного окна рабочему столу и выполняя собственный рисунок, но не смог увидеть никаких сообщений на рабочем столе.

В идеале я хотел бы сделать это в WPF, а не в окнах вообще. Любая подсказка, как создать окно WPF, которое я могу нарисовать, находится под значками рабочего стола, но поверх обоев, так что оно игнорирует любые сообщения мыши, и рабочий стол продолжает работать нормально?

Ответы [ 2 ]

2 голосов
/ 07 мая 2009

Если вы получите дескриптор окна рабочего стола, вы можете создать новое окно и добавить свое собственное окно в качестве дочернего элемента этого. Поместив его за представление списка, вы получите нужный результат, хотя я не уверен на 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);


        }

    }
1 голос
/ 07 мая 2009

Я сделал это, заставив мое окно ответить на сообщение WM_WINDOWPOSCHANGING, установив WINDOWPOS.hWndInsertAfter = HWND_BOTTOM. Это говорит ОС: убедитесь, что мое окно находится под всеми остальными окнами, и оно выглядит так, как будто ваше окно приклеено к рабочему столу.

...