Рисунок на фоне рабочего стола как замена обоев (Windows / C #)

Я пытаюсь создать приложение, которое должно рисовать на рабочем столе за значками, чтобы оно заменяло обои рабочего стола. Я нашел несколько решений для этого, но большинство из них работали не очень хорошо (много мерцания). Одно решение кажется мне тем, что я ищу, но на самом деле я его не понимаю. Я делал в основном приложения C # с использованием графических библиотек более высокого уровня или только Windows Forms, а также немного C ++, но только на платформах, отличных от Windows.

Если бы кто-нибудь мог «перевести» это для меня или предоставить альтернативное решение, я был бы очень признателен!


person nardi    schedule 05.11.2009    source источник


Ответы (5)


Я так и не нашел решение, которое хотел, но вот лучшие (только?) Альтернативы:

  • Нарисуйте в окне "SysListView32" (ProgMan -> SHELLDLL_DefView -> SysListView32). Он будет отображаться за значками на рабочем столе, но будет мерцать при использовании анимации. Как: Ссылка (вам придется использовать взаимодействие в .NET).

  • Используйте наложения DirectDraw. Вы устанавливаете цвет рабочего стола на определенный неясный цвет, и все, что имеет этот цвет, будет заменено тем, что находится на оверлее. Это используется в примере в моем вопросе и в режиме обоев VLC. Однако это несовместимо с Aero. Как: Ссылка (я думаю, вы могли бы использовать управляемый DirectX в .NET?).

person nardi    schedule 07.01.2010
comment
К сожалению, насколько мне известно, нет. Я как бы отказался от того, чем пытался заниматься, кажется, что на самом деле это невозможно. - person nardi; 12.12.2012
comment
Это очень поздно, но я смог сделать это с помощью этого ссылка. - person Clark; 11.08.2015
comment
@Clark, на мой взгляд, вы могли бы опубликовать это как ответ. Это ответ на этот вопрос, который упростит поиск тех, кто попадает на эту страницу. Также OP должен установить его как правильный ответ. - person Barnack; 14.05.2019

Я знаю, что это довольно поздний ответ, но я недавно сам изучил его, и если у других пользователей возникнет такая же проблема, это может им помочь.

ПРИМЕЧАНИЕ. Этот ответ предназначен для C ++, но, возможно, он поможет вам сделать то же самое на C #.

Как упоминалось в комментарии выше, я следовал этому руководству, чтобы понять, как я могу нарисовать ON окно обоев 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;
}

Мне удалось получить дескриптор окна.

Поскольку я был знаком только с SDL, это было единственное решение, которое я нашел, но я считаю, что любые способы, позволяющие создавать / изменять окно на основе другого окна, должны работать.

window = SDL_CreateWindowFrom((void*)get_wallpaper_window());

Строка выше позволила мне создать окно в SDL из HWND, полученного методом get_wallpaper_window().

Поскольку задействовано много кода, я свяжу свое решение на github. Это может нарисовать много звезд (хотя я считаю, что это можно улучшить) за вашими значками на рабочем столе.

person darclander    schedule 31.10.2020

Вы можете найти вдохновение в коде медиаплеера VLC. есть режим обоев, который сделает то, что вы ищете.

person Géal    schedule 05.11.2009

Попутно рассмотрел этот вопрос, и я частично решил проблему (но не в том смысле, в котором я могу дать какой-либо полезный код), чтобы создать несколько классных игр, хотя может не иметь нужного вам приложения:

  • Установите нормальный фон рабочего стола и сделайте снимок экрана рабочего стола.
  • Установите черный фон рабочего стола и сделайте снимок экрана рабочего стола.
  • Установите белый цвет фона рабочего стола и сделайте снимок экрана рабочего стола.
  • Объедините черно-белую версию, чтобы создать маску и первый снимок экрана в качестве значений пикселей наложения, которые отличаются прозрачностью.

Теперь в вашей форме нарисуйте следующее по порядку:

  1. Нарисуйте первый скриншот
  2. Нарисуйте свою форму
  3. Нарисуйте созданный вами оверлей рабочего стола

Это то, что я сделал для полноэкранной формы, но я думаю, что его можно довольно легко адаптировать для неполноэкранных форм. По сути, вы воссоздали рабочий стол, но теперь можете делать с ним все, что угодно, включая несколько крутых игр. Скорость отрисовки и производительность удовлетворительны для любого приложения, но интерактивность рабочего стола является проблемой ... :( Вот изображение игры с танками, использующее этот принцип, за исключением того, что я установил белый фон и сделал все белые фоны прозрачными!

Игра "Мои танки"

person William Dutton    schedule 03.03.2014

Да, с взаимодействием, см. эту ветку.

person luvieere    schedule 05.11.2009
comment
Это нарисовало бы поверх всего; Я хочу рисовать за всем (кроме обоев рабочего стола). - person nardi; 06.11.2009