Сейчас попробовал проделать то, что описал. Действительно не все гладко. Итак по-порядку.
Для отправки сообщений я воспользовался своей старой утилиткой AppMsg (исходник прилагаю). Это консольная утилитка и служит она для отправки сообщения окну по названию его класса и/или заголовку. Можно указать код сообщения или его имя. Можно выбирать способ отправки POST/SEND и указывать параметры.
Писал я ее для того, чтобы запуском одного командного файла можно было закрывать несколько приложений. Вот пример одного из них (служит для закрытия лишних программ перед запуском игр - чуть-чуть меньше тормозов в результате):
Код:
net stop incdsrv
net stop mssql$starteam
net stop mysql
net stop OutpostFirewall
net stop Apache
net stop Spooler
appmsg "FarStone_VirtualDrive_PersonalVersion_VDTASK_3F64B089-A8AE-4488-8FC7-A2D39340F3C4" * WM_CLOSE POST
appmsg * "Клавиатурный Ниндзя 1.7" WM_CLOSE POST
appmsg * "Chameleon Clock" WM_CLOSE POST
Итак с инструментарием разобрались, теперь к делу.
В качестве первого подопытного кролика я выбрал окно справки
Win 32 Programmer`s Reference оно как раз открыто было на теме WM_COMMAND (это стандартный справочный файл из поставки Delphi ищи его в главном меню), хотя пройдет и с любым другим файлом справки - открывает их одна и таже программа просмотра справочных файлов.
Запускаем WinSight и настраиваем как в предыдущем посте, разве что в Messages->Options я еще в нижней части все птички поставил - чтобы получить более подробный лог.
Запускаем логирование Messages->Selected Windows, переключаемся на исследуемое окно и кликаем например так "Параметры->Размещение окна справки->Поверх остальных" а затем "Параметры->Размещение окна справки->Обычное". Наблюдаем в логе следующие строки:
Код:
01527.366 000005:005803C8 "Win32 Progr" WM_COMMAND (11104X) Dispatched wp=000005BF lp=00000000 Menu 05BFh 1471d
01528.768 000006:005803C8 "Win32 Progr" WM_COMMAND (11104X) Dispatched wp=000005BE lp=00000000 Menu 05BEh 1470d
Здесь
01527.366 - время,
000005 - порядковый номер записи,
005803C8 - hwnd окна,
"Win32 Progr" - заголовок окна,
WM_COMMAND (11104X) - сообщение,
wp=000005BF lp=00000000 - параметры,
Menu 05BEh 1470d - ID элемента меню в шестнадцатеричном и десятичном виде (совпадает с wp).
Ну чтож попробуем сами послать сообщение при помощи рассмотренной утилиты:
Код:
appmsg "MS_WINDOC" * WM_COMMAND POST 1471 0
Видим что окно справки действительно прыгнуло в положение "Поверх остальных" и птичка в меню переключилась в соответствующее положение.
Код:
appmsg "MS_WINDOC" * WM_COMMAND POST 1470 0
И все опять вернулось на свои места.
Теперь о грустном. Я попробовал проделать тоже самое со стандартным блокнотом. И тут меня ждал жестокий облом - я так и не смог отловить какое именно сообщение посылается при выборе пункта меню в данной программе. Видимо взаимодействие с меню там реализовано по-другому.
Вывод
Похоже не со всеми программами пройдет такой трюк. В каждом конкретном случае необходима проверка.