DirectX Desktop - PullRequest
       10

DirectX Desktop

19 голосов
/ 12 апреля 2010

Я бы хотел сделать анимированный фон рабочего стола для Windows 7, используя DirectX. Я использую C #, SlimDX и несколько импортов функций Windows API P / Invoke. Я не очень разбираюсь в нативном программировании на Windows, но у меня есть опыт работы в Интернете, и я считаю, что мне нужно сделать следующее:

1) Найдите дескриптор окна, содержащего обои dekstop, подключите его к устройству DirectX и нарисуйте в нем.

2) Создайте новое окно вывода и вставьте его над обоями рабочего стола, но под значками рабочего стола.

Я пробовал оба этих варианта, но ни один из них не работает. Если я перемещаюсь по иерархии окон, начиная с дескриптора, возвращенного GetDesktopWindow (), я могу перейти на рабочий стол -> WorkerW -> SHELLDLL_DefView -> SysListView32. Если я подключу устройство DirectX к этому дескриптору, я могу нарисовать весь рабочий стол, но он также покрывает значки. Если я создаю форму Windows, устанавливаю для ее родителя значение SHELLDLL_DefView с помощью SetParent (), а затем использую SetWindowPos, чтобы играть с ее Z-порядком, я могу только заставить ее идти либо за обоями рабочего стола, либо перед значками рабочего стола +.

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

Кто-нибудь знает, что я должен делать, или даже возможно ли то, что я хочу сделать? Кажется, вы можете рисовать на фоне рабочего стола с помощью GDI (как я полагаю, это делает программа wxSnow), и я видел нечто похожее на то, что я хочу сделать в VLC Media Player под Windows XP с его режимом обоев DirectX (интересно, я не могу включить эту опцию в моей системе).

Спасибо!

Ответы [ 3 ]

5 голосов
/ 12 апреля 2010

Похоже, это невозможно.Смотрите эту ссылку:

http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/69839cec-3424-4300-9ac3-486b8c2fe492

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

  1. Создание пользовательского элемента управления в библиотеке элементов управления Windows.
  2. Включение пользовательского элемента управления в элемент управления ActiveX.
  3. Включение элемента управления ActiveX на веб-странице.
  4. Включение активногорабочего стола и установите веб-страницу в качестве фона рабочего стола.

Это можно сделать только в XP, поскольку Vista не поддерживает активный рабочий стол.

В другом посте предлагаетсячто вы могли бы сделать это с фоном окна проводника - если бы вы могли получить дескриптор окна, которое его составляет.Конечно, если это возможно, то возможно также получить дескриптор окна рабочего стола за значками.

Обновление: Ну, пока единственное, что я обнаружил, этоможет «работать», просто создавая растровые файлы и меняя обои снова и снова (я подозреваю, что это будет медленно, как вы упоминали).

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

Обновление 2: Это может сработать, но я не уверен:

http://social.msdn.microsoft.com/forums/en-US/vcgeneral/thread/4af734fb-d2c1-414b-a9f1-759b76692802

В сущности, это так:

HWND p = FindWindow("ProgMan", NULL);
HWND s = FindWindowEx(p, NULL, "SHELLDLL_DefView", NULL);
HWND dtw = FindWindowEx(s, NULL, "SysListView32", NULL);
HDC hdc = GetDC(dtw);

Вы в основном начинаете с окна ProgMan и углубляетесь в обои рабочего стола (я полагаю, "SysListView32").Я собираюсь попробовать это.

Обновление 3: Не пойдет - приведенный выше код получает DC рабочего стола, но он находится над значками, поэтому BitBlt рисует поверх них.Однако он не рисует на экране, потому что я могу рисовать под открытой формой, не закрывая ее, так что, по крайней мере, это прогресс.

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

Обновление 4: Я почти уверен, что что-то с помощью этого будет работать:

http://msdn.microsoft.com/en-us/library/bb761155(v=VS.85).aspx http://msdn.microsoft.com/en-us/library/bb774742(v=VS.85).aspx

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

Предоставляет ли DirectX фреймы в качестве дескрипторов растровых изображений (GDI-совместимых) или только DC?В моем случае моя анимация уже представляет собой массив GDI-совместимых растровых изображений, поэтому у меня не возникло бы проблем с использованием этого подхода.Если это единственный маршрут, и DirectX не предоставляет дескрипторы растрового изображения (и я не думаю, что они это сделают), то для каждого кадра вам нужно будет создать новое растровое изображение GDI, которое значительно замедлит работу.

На самом деле, может быть более простой способ, хотя я не уверен, что это сработает.Как только вы получите указатель на фактическое растровое изображение обоев, вы можете выбрать его в контексте устройства, используя SelectObject, а затем просто использовать этот контекст устройства в качестве пункта назначения BitBlt.Возможно, вам придется отправить инструкцию по перерисовке на рабочий стол, что может привести к тому, что значки будут перерисовываться каждый раз.

Как насчет работы здесь?:)

1 голос
/ 14 апреля 2010

Я сделал некоторую анимацию альфа-смешанных окон , которые всегда находятся на вершине Z-порядка. Одной из идей было бы игнорировать попытки изменить растровое изображение рабочего стола и просто нарисовать ваши вещи в виде многослойного окна , но каким-то образом управлять ZOrder, чтобы оно всегда было самым нижним, не настольным окном (возможно, путем стратегического вызова Form.SendToBack() или что-то в нужное время).

В зависимости от того, что вы пытаетесь сделать, это может дать вам тот же эффект анимации рабочего стола.

1 голос
/ 12 апреля 2010

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

Вы действительно используете рабочий стол для иконок? В Windows 7 функция поиска в меню «Пуск» и новая панель задач не позволяют использовать значки на рабочем столе.

Просто идея

Возможно изменить окно рабочего стола с помощью SendMessage (GetDesktopWindow, WM_SOME_MESSAGE, wParam, lParam), чтобы вы могли достичь желаемого. Я мог бы продолжить расследование завтра (сейчас 3 часа утра по местному времени).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...