Замена обоев рабочего стола / рисования на рабочий стол

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

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

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

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


person Community    schedule 07.05.2009    source источник


Ответы (2)


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


        }

    }
person Tom Clarkson    schedule 07.05.2009
comment
Спасибо - не могли бы вы указать мне на добавление дочернего элемента в существующее окно? Я не вижу очевидной функции API для этого. - person ; 07.05.2009
comment
Это все, что касается pinvoke - прошло несколько лет с тех пор, как я это сделал, но я думаю, вы захотите найти sethwndparent или setwindow. - person Tom Clarkson; 07.05.2009
comment
Кажется, что создание формы и добавление ее в качестве дочернего элемента списка на рабочем столе почти работает. Форма находится под всеми другими окнами, но все еще над значками. Есть идеи, как по-настоящему вернуть его на задний план / обои? - person ; 08.05.2009
comment
Программа, для которой я написал это, заменяла значки, поэтому проблема не возникла. Вероятно, вы захотите установить форму как дочернюю по отношению к родительскому элементу представления списка, а затем установить zindex, чтобы поместить его за представлением списка. - person Tom Clarkson; 09.05.2009

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

person Tim Robinson    schedule 07.05.2009
comment
Это дает немного другой результат - ваше окно будет перед любыми дочерними окнами рабочего стола, и я считаю, что функция отображения рабочего стола заставит его исчезнуть. - person Tom Clarkson; 08.05.2009