Подтвердить что ты не робот

Рабочий стол DirectX

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

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

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

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

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

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

Спасибо!

4b9b3361

Ответ 1

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

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

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

  • Создайте свой пользовательский элемент управления в библиотеке управления Windows.
  • Вставьте элемент управления пользователя в элемент управления ActiveX.
  • Вставить элемент управления ActiveX на веб-странице.
  • Включить активный рабочий стол и настроить веб-страницу на рабочем столе фон.

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

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

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

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

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

Как насчет вас здесь?:)

Ответ 2

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

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

Только идея

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

Ответ 3

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

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