WM_SETFOCUS, получить приложение, которое только что потеряло фокус

Когда мое приложение WTL C++ активируется или получает фокус клавиатуры, мне нужно определить дескриптор окна приложения, которое ранее было активировано/имело фокус. Однако дескрипторы окон (LPARAM) обоих сообщений WM_SETFOCUS и WM_ACTIVATE являются NULL (XP, 32 бита).

Как я могу определить приложение, которое только что потеряло фокус, когда мое приложение активировано? Есть ли простой способ сделать это или мне нужно будет крутить специальный крючок CBT?


person Rob    schedule 03.03.2011    source источник


Ответы (1)


Простой способ узнать, какие именно сообщения отправляются и каковы их параметры, — запустить Spy++ и установить для него значение «Журнал сообщений», пока вы нажимаете Alt+Tab в другое окно.

В соответствии с тем, что вы обнаружили, lParam для обоих WM_SETFOCUS и WM_ACTIVATE будет NULL, когда ранее активное окно (или активное окно) не находится в том же потоке.

Возможно, вам больше повезет с WM_ACTIVATEAPP, как предложил Дэвид. Получив идентификатор потока, вы можете попробовать вызвать GetGUIThreadInfo функцию, чтобы определить активное окно для этого потока. Эта функция будет работать, даже если активное окно не принадлежит вызывающему процессу.

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

Если вы не боитесь использовать вещи, которые могут сломаться в будущих версиях Windows, вы можете исследовать RegisterShellHookWindow функция. Я не могу вам много рассказать об этом, так как сам никогда им не пользовался, но это более простой способ получить сообщения оболочки, которые вы в противном случае получили бы, только установив ловушку.
Это было еще в Windows 2000, но не был включен в SDK до XP SP1. Насколько я могу судить, он все еще существует в Windows Vista и 7.

person Cody Gray    schedule 03.03.2011
comment
+1 Я и забыл про RegisterShellHookWindow! Я использую его в своем приложении, чтобы определить, когда файл справки моего приложения .chm закрывается, чтобы я мог запомнить его размер и положение и восстановить его, когда он снова запустится. Красный текст предупреждения вызывает беспокойство, но, похоже, он отлично работает на версиях от XP до 7. - person David Heffernan; 03.03.2011