
Как получить список подсказок у иконок в трее
Сегодня снова будем издеваться над треем. На этот раз для доступа к данным в трее будем использовать средства интерфейса IAccessible, ранее мы его уже применяли, но немного для других задач.Структуры, константы, интерфейсы и все остальное уже расписано в статье по ссылке выше, дублировать не буду. Как пройтись по иерархии окон Проводника и получить хэндл трея с иконками тут тоже было немало примеров. Переходим к основной части.
Code (Assembler) : Убрать нумерацию
- ; Получить информацию о выбранном элементе
- ; [hTray] - хэндл окна трея с иконками
- invoke AccessibleObjectFromWindow,[hTray],OBJID_CLIENT,\
- CLSID_IAccessible,pAcc
- ; Количество элементов в окне
- mov eax,[pAcc]
- mov eax,[eax]
- stdcall dword [eax+IAccessible.get_accChildCount],[pAcc],tmp
- invoke wsprintf,buff,mask1,[tmp]
- add esp,12
- stdcall AddLog,[hwmain],ID_LOG,buff
- ; Начинаем перебирать с 1 элемента
- mov ebx,1
- loc_loop:
- ; Выделить память под строку
- invoke SysAllocString,szNull
- mov [bstrName],eax
- ; Получить название выбранного элемента
- push [bstrName]
- mov [varChild.vt],VT_I4
- mov [varChild.lVal],ebx
- mov eax,varChild
- push dword [eax+0Ch]
- push dword [eax+08h]
- push dword [eax+04h]
- push dword [eax]
- mov eax,[pAcc]
- mov eax,[eax]
- stdcall dword [eax+IAccessible.get_accName],[pAcc]
- ; Строка подсказки
- mov eax,[bstrName]
- mov eax,[eax]
- ; EAX -> строка подсказки
- ; Прибраться за собой
- invoke SysFreeString,[bstrName]
- ; Следующий элемент
- inc ebx
- cmp ebx,[tmp]
- jbe loc_loop
- ; Прибраться за собой
- mov eax,[pAcc]
- mov eax,[eax]
- stdcall dword [eax+IAccessible.Release],[pAcc]
Список подсказок и количество иконок получать научились, теперь о практическом применении этого трюка. С точки зрения устройств для чтения с экрана все элементы трея имеют тип "Кнопка" с единственным действием "Нажать". А у интерфейса IAccessible есть интересный метод accDoDefaultAction, который в данном случае соответствует клику на выбранной иконке. Некоторые программы не поддерживают горячие клавиши и отображают свое окно только при нажатии иконки в трее. Так ведет себя, к примеру, десктопная версия Telegram: по хоткею в трей сворачивается, а обратно никак. Или, например, комбинация клавиш для активации окна какой-нибудь программы прибита гвоздями и конфликтует с другим приложением, но главное окно можно вызвать также кликом на иконку в трее. В перечисленных случаях можно написать микро-приложение, которое будет постоянно висеть в памяти, забиндит на себя удобные вам комбинации клавиш, при их нажатии пробежится по системному трею, по подсказкам или их характерным фрагментам определит нужное приложение и "кликнет" на его иконке.
В приложении пример программы с исходным текстом, которая получает список подсказок у иконок из системного трея, а в случае обнаружения иконки десктопной версии Telegram "кликнет" на ней.
Просмотров: 538 | Комментариев: 7

Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
Vladimir
(27.03.2025 в 11:15):
Да, я в ней тоже толком плюсов не вижу критичных, но всё больше софта ставится минимум на 10, да и дрова на свой ноут три года назад были уже только на 10. У Мозиллы вот всё хуже со старыми системами. Но это оффтоп, понимаю.

ManHunter
(27.03.2025 в 11:06):
Не пользуюсь ни x64, ни Win10.

Vladimir
(27.03.2025 в 11:00):
Вчера неожиданно понадобилось прочитать информацию из трея (тултип и, в идеале, иконку), но так ничего и не добился. Я, впрочем, в WinAPI не силён, университетский курс много лет назад.
Ваш код работает, адаптирую под себя, но стало интересно. Может вы подскажете, можно ли сейчас в Win10 x64 сделать это как-то без инжектов dll и аналогичного? Или Майкрософт вообще всё позакрывали? Вдруг вы сталкивались.
Ваш код работает, адаптирую под себя, но стало интересно. Может вы подскажете, можно ли сейчас в Win10 x64 сделать это как-то без инжектов dll и аналогичного? Или Майкрософт вообще всё позакрывали? Вдруг вы сталкивались.

ManHunter
(13.03.2024 в 15:36):
Опять же, это такое поведение трея с той позиции, как если бы его увидела экранная читалка. Программа не придумывает данные, пользуется стандартными функциями системы с не менее стандартным доступом к ним.

==DJ==[ZLO]
(13.03.2024 в 15:30):
Может сморожу чушь но, я по расписанию запускаю Get.Tray.Tips и при этом открываю шторку в трее всего 8мь элементов в шторке три, после таймера выполняется Get.Tray.Tips и показывает 5ть. Хотя на экране 8мь. Вот что я имел ввиду.

ManHunter
(06.03.2024 в 11:36):
Так это вполне ожидаемое поведение. Тут же работа выполяется через функции экранной читалки, а раз чего-то не видно на экране, то "прочитать" это не представляется возможным.

==DJ==[ZLO]
(06.03.2024 в 09:42):
Спасибо, полезно. А те, которые за "шторкой" она не выводит (

Добавить комментарий
Заполните форму для добавления комментария
