Разрешить фоновое приложение, чтобы установить переднее окно другого процесса

Во-первых, я знаю, что это спорная дискуссия, но я надеюсь, что мы сможем сохранить эту техническую информацию.

У меня есть приложение, которое запускается в фоновом режиме, и я как-то хочу, чтобы оно могло активировать / переносить окно в другом процессе. Но вызов SetForegroundWindow всегда терпит неудачу, даже если процесс, окно которого я хочу активировать, вызвал AllowSetForegroundWindow(ASFW_ANY).

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

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

Однако, если я позвоню

AttachThreadInput(
    GetWindowThreadProcessId(GetForegroundWindow(), NULL),
    GetCurrentThreadId(), TRUE);

перед созданием фиктивного окна оно действительно создается на переднем плане, и после этого я могу вызвать SetForegroundWindow для другого HWND в другом процессе, который работает.

НО: если я не создаю фиктивное окно, SetForegroundWindow по-прежнему возвращает ноль, хотя я использую AttachThreadInput.

Я не понимаю, почему взлом AttachThreadInput успешен, если я создаю собственное Окно (и после этого успешно работает для других окон), но безуспешен, если сначала я не создаю собственное окно.

Как мой фоновый процесс может вызвать SetForegroundWindow для другого окна в другом процессе, не создавая фиктивное окно?

[*] Фоновым приложением на самом деле является gpg-agent.exe, который вызывает pinentry.exe (мое приложение) всякий раз, когда запрашивается пароль. pinentry.exe (запущенный как фоновый процесс) должен запросить пароль у другого работающего приложения, поэтому он должен вывести свое окно на передний план...

1 ответ

Документация для AttachThreadInput() дает вам подсказку:

Окна, созданные в разных потоках, обычно обрабатывают ввод независимо друг от друга. То есть они имеют свои собственные состояния ввода (фокус, активное, окна захвата, состояние ключа, состояние очереди и т. Д.), И их обработка ввода не синхронизирована с обработкой ввода других потоков. Используя функцию AttachThreadInput, поток может присоединить свой механизм обработки ввода к другому потоку. События клавиатуры и мыши, полученные обоими потоками, обрабатываются потоком, заданным параметром idAttachTo, до тех пор, пока потоки не будут отсоединены, во второй раз вызвав AttachThreadInput и указав FALSE для параметра fAttach. Это также позволяет потокам совместно использовать свои состояния ввода, поэтому они могут вызывать функцию SetFocus, чтобы установить фокус клавиатуры на окне другого потока. Это также позволяет потокам получать информацию о состоянии ключа.

Документация для SetForegroundWindow() говорит вам, каким критериям должен соответствовать вызывающий процесс, чтобы установить окно переднего плана:

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

Процесс - это процесс переднего плана.
Процесс был начат процессом переднего плана.
Процесс получил последнее входное событие.
Там нет переднего плана процесса.
Процесс отлаживается.
Процесс переднего плана не является современным приложением или стартовым экраном.
Передний план не заблокирован (см. LockSetForegroundWindow).
Истекло время ожидания блокировки переднего плана (см. SPI_GETFOREGROUNDLOCKTIMEOUT в SystemParametersInfo).
Нет активных меню.

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

Другие вопросы по тегам