Windows 7 по-разному относится к полноэкранным приложениям? - PullRequest
1 голос
/ 30 июня 2010

У меня есть скрытый процесс, который ожидает нестандартных аппаратных сообщений о кнопках и запускает приложение (с CreateProcess).Нет проблем с беспокойством пользователя, это действие, которое пользователь одобрил сам.Все хорошо, когда это обычный макет с панелью задач и окнами с несколькими заголовками и без заголовков.Но ситуация отличается в XP и 7, когда текущее приложение полноэкранное.Полноэкранное приложение в этом случае - это окно без границ, имеющее точно такой же размер, что и экран.Windows скрывает панель задач для такого приложения, даже если она всегда включена.

В Xp все в порядке, в этом случае отображается панель задач и приложение (например, калькулятор), полноэкранное приложение все еще видно в областях, отличных от запущенного приложения и панели задач '.Но в Windows 7 ничего визуального не происходит, полноэкранное приложение все еще включено, и если я переключаюсь на панель задач, исполняемое приложение остается там.Я пытался решить это с помощью SetForegroundWindow, BringWindowToTop, даже вызова AllowSetForegroundWindow (GetCurrentProcessId ()) для дескриптора окна, найденного с помощью CreateProcess-WaitForIntputIdle-EnumThreadWindows, без изменений.Так что же изменилось с тех пор, как в XP появились полноэкранные окна, которые официально задокументированы?

Спасибо,

Макс

Ответы [ 3 ]

1 голос
/ 30 июня 2010

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

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

К сожалению, у меня нет хорошего решения вашей проблемы.Один из способов решить эту проблему - добавить стиль WS_CAPTION в ваше приложение, а затем обработать WM_NCPAINT / WM_NCCALCSIZE / WM_NCHITTEST самостоятельно.Это позволит вам соврать DWM, что вы обычное оконное приложение, но визуально измените область NC, чтобы выглядеть так, будто у вас нет заголовка.Тем не менее, это требует определенного количества дополнительного кода и может потребовать немного больше усилий, которые вы хотите инвестировать.

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

Кстати, вы можете найти комментарии к этому посту от Раймонда Чена интересными.

1 голос
/ 30 июня 2010

Я полагаю, что, если у вас есть собственное аппаратное устройство, есть некоторый API для генерации «реального» пользовательского ввода.Очевидно, что устаревшая клавиатура и мышь, а теперь драйверы USB HID (многие из которых являются пользовательскими, я думаю?) Имеют доступ к API для этого.

Например, Synergy + может генерировать поддельные события клавиатуры и мыши на подключенных ПКи следствием ложного ввода является активация переключения Windows в обычном режиме.

Итак, моя первоначальная идея состоит в том, чтобы ваше пользовательское приложение «Устройство» синтезировало реальные сообщения клавиатуры - SendInput кажется вероятным кандидатом на «API, который может«поддельные» события реального ввода пользователя.

Затем используйте API-интерфейс, такой как RegisterHotKey, в своем приложении «UI», чтобы ответить на комбинацию горячих клавиш, которую генерирует приложение вашего устройства.

Сейчас (при условии, что SendInputЕсли вы генерируете события пользовательского ввода на правильном уровне), вы должны (изнутри обработчика WM_HOTKEY в вашем приложении пользовательского интерфейса) иметь разрешение (потому что все было «инициировано пользователем») для изменения окна переднего плана (для себя).

0 голосов
/ 30 июня 2010

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

Вы можете узнать, на каком рабочем столе запущено приложение, используя Process Explorer:

  • Установите Process Explorer для замены Task Managerи для запуска всегда сверху.
  • Когда отображается полный экран вверх, запустите Process Explorer, нажав Ctrl + Shift + Esc
  • В Process Explorer выберите полноэкранный процесс и нажмите Ctrl +H для отображения маркеров этого процесса
  • См. Значение элемента Desktop в списке.Обычно для этого устанавливается значение По умолчанию

Если вы знаете, на каком рабочем столе запущено это приложение, вы можете запустить процесс на том же рабочем столе, сначала позвонив по номеру OpenDesktop, чтобы получить дескриптор этого рабочего стола, а затем передать его в STARTUPINFO вашего CreateProcess вызова.

...