Как надежно украсть / восстановить фокус для приложения MFC / desktop на Windows 8.1 / 10? - PullRequest
0 голосов
/ 12 сентября 2018

ОК, я понял: воровство фокуса - зло .Или, по крайней мере, это 99,9% времени.Но мне действительно нужно надежно украсть фокус на Windows 8, и до сих пор меня смущает толпа людей, настаивающих на том, что кража фокусов всегда зло.

Сценарий: мы запускаем кастомприложение на обычном ПК под управлением Windows 8.1 (скоро будет Windows 10).Экран, клавиатура и мышь находятся примерно в 5 метрах от земли, вверх по лестнице, на которую оператор погрузчика не должен подниматься.Единственное устройство ввода, которое у них есть, это цифровая клавиатура на удлинительном кабеле на их уровне.Все, что им нужно делать, они могут делать с этой клавиатуры ... до тех пор, пока какая-то злая программа не украла фокус нашего приложения или какой-то удаленный пользователь не вышел из системы и не оставил другое приложение с фокусом.

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

В Windows 7 с использованием SetForegroundWindow() (включено с помощью AllowSetForegroundWindow() работает нормально - приложение можно вернуть на передний план и возобновить фокусировку. В Windows 8 SetForegroundWindow() приводит только к миганию значка панели задач, но приложение не восстанавливает фокус, заставляя нашего пользователяподниматься по лестнице ... там, где полная клавиатура и мышь слишком заманчивы для того, чтобы они не нажимали кнопки, которые им не следует делать, и обычно возникает хаос.

Так что, пожалуйста, сэр: может ли наше (MFC, настольное) приложениеукрадите фокус, как только мышь на 1 минуту простаивает, потому что это более или менее единственное приложение, которое обычно должно работать в любом случае. Если это разрешено, как мы можем надежно украсть его?

Ответы [ 3 ]

0 голосов
/ 12 сентября 2018

Настройка горячих клавиш на цифровой клавиатуре (RegisterHotKey).

Нажатие зарегистрированной горячей клавиши дает вам любовь активации переднего плана от Раймонда Чена

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

0 голосов
/ 18 сентября 2018

Возможное решение (с основными ограничениями): не делать ничего лишнего; ждать.

Один из наших специалистов по обслуживанию заметил, что при третьей или четвертой попытке восстановить фокусировку с использованием AllowSetForegroundWindow() и SetForegroundWindow(), как это было в Windows 7, Windows 8, наконец, позволила нашему приложению восстановить фокус. Неясно, какие условия делают эту работу или надежно ли она работает, но теперь мы наблюдаем, как наше приложение восстанавливает фокус из-за Chrome, из-за другого (самостоятельно разработанного) приложения MFC и из-за стороннего приложения - все настольные приложения. Приблизительно 3-4 минуты должно было пройти в каждом случае, прежде чем фокус был возвращен к нашему (настольному) приложению.

Тем не менее, мы не стали свидетелями того, как он вновь обратил внимание на приложения из метро, ​​и не ожидаем этого (например, нажмите клавишу Windows и оставьте систему задерживаться на начальном экране).

В нашей (ограниченной) ситуации мы готовы пойти на риск, что наши пользователи не будут запускать приложение метро, ​​которое скрывает наше настольное приложение, по крайней мере, без восстановления нашего приложения, поскольку их бизнес полагается на него. Нашей главной заботой является то, что один из наших занятых сервисных техников войдет в систему удаленно, отвлечется и небрежно оставит одну из наших настольных утилит в центре внимания. Ожидание 3-4 минут является решением этого конкретного сценария.

0 голосов
/ 12 сентября 2018

Я бы попробовал это так:

  1. Установите таймер в вашем приложении.Это проверяет GetForegroundWindow на регулярной основе.
  2. Если GetForgroundWindow не принадлежит вашему процессу (GetWindowThreadProcessId)
  3. Если другой процесс отображается в окне переднего плана, используйте AttachThreadInput иприсоедините свою входную очередь к входной очереди другого процесса.
  4. Теперь используйте SetForegoundWindow и снова отсоедините поток ввода.
  5. Теперь вы можете использовать SetFocus по мере необходимости для управления вводомфокус вашей программы.
...