Blog. Just Blog
Принудительное обновление иконок в трее
В случае аварийного завершения или некорректной работы некоторых приложений, в системном трее могут оставаться "мертвые" иконки, которые уже не принадлежат ни одному запущенному процессу. Глюк хоть и не смертельный, но все равно неприятный. И основная проблема в том, что область трея никак не реагирует на внешние сообщения типа WM_REPAINT, и функции типа UpdateWindow и InvalidateRect. То есть автоматически обновить или перерисовать его, чтобы избавиться от "мертвых" иконок, не получится. Но такие иконки удаляются, если провести курсором мышки над ними. Значит единственный способ перерисовать иконки в трее - это сэмулировать движение мыши над окном трея. Как найти окно трея и его хэндл мы уже знаем, тут ничего нового. В сегменте данных те же значения:Code (Assembler) : Убрать нумерацию
- ; Сегмент данных
- section '.data' data readable writeable
- class1 db 'Shell_TrayWnd',0 ; Название класса окна трея
- class2 db 'TrayNotifyWnd',0 ; Название класса панели уведомлений
- class3 db 'SysPager',0 ; Трей
- class4 db 'ToolbarWindow32',0 ; Панель с иконками
- ToolbarHandle dd ? ; Хэндл окна трея
- ToolbarRect RECT ; Размер окна трея
Code (Assembler) : Убрать нумерацию
- ; Найти окно трея
- invoke FindWindow,class1,NULL
- or eax,eax
- jz exit_process
- ; Найти панель уведомлений
- invoke FindWindowEx,eax,NULL,class2,NULL
- or eax,eax
- jz exit_process
- ; Найти трей
- invoke FindWindowEx,eax,NULL,class3,NULL
- or eax,eax
- jz exit_process
- ; Найти панель иконок в трее
- invoke FindWindowEx,eax,NULL,class4,NULL
- or eax,eax
- jz exit_process
- ; Сохранить хэндл окна с иконками
- mov [ToolbarHandle],eax
И, собственно, сам код. Обратите внимание, что сообщения трею мы отправляем через PostMessage, чтобы не тратить время на ожидание от него ответа.
Code (Assembler) : Убрать нумерацию
- ; Получить размеры окна трея
- invoke GetClientRect,[ToolbarHandle],ToolbarRect
- ; Эмуляция движения мыши над окном трея
- xor esi,esi
- loc_move_line:
- xor edi,edi
- loc_move_column:
- ; y << 16
- mov eax,esi
- shl eax,16
- ; x
- add eax,edi
- ; Отправить сообщение движения мыши
- invoke PostMessage,[ToolbarHandle],WM_MOUSEMOVE,NULL,eax
- ; Следующий столбец
- add edi,16
- cmp edi,[ToolbarRect.right]
- jb loc_move_column
- ; Следующая строка
- add esi,16
- cmp esi,[ToolbarRect.bottom]
- jb loc_move_line
В приложении пример программы, обновляющей иконки в трее описанным в статье способом. Для тестов прилагается программа, которая устанавливает свою иконку в трей, и не удаляет ее после выхода.
Просмотров: 1919 | Комментариев: 6
Комментарии
Отзывы посетителей сайта о статье
SAY
(17.01.2012 в 19:37):
Точно также делал в одном приложении у себя. Очень огорчило отсутствие нормального обновления.
ManHunter
(12.01.2012 в 09:15):
Обрабатывать сообщение минимизации окна, отслеживать скрытие (ShowWindow + SW_HIDE) своего окна из сторонних приложений.
Dimas
(12.01.2012 в 08:08):
Спасибо, пример поглядел все понятно и работает
Немного неправильно я выразился - программу требуется прятать в трей при нажатие кнопки свернуть все (или свернуть все окна) или при нажатие win+D
Где-то на форумах советовали отслеживать события окон, была даже чья-то мысль обратиться к разработчику total-а)) Вообщем в итоге так ничего и не нашел.
Немного неправильно я выразился - программу требуется прятать в трей при нажатие кнопки свернуть все (или свернуть все окна) или при нажатие win+D
Где-то на форумах советовали отслеживать события окон, была даже чья-то мысль обратиться к разработчику total-а)) Вообщем в итоге так ничего и не нашел.
ManHunter
(11.01.2012 в 20:26):
По таймеру через GetForegroundWindow получаешь активное окно, находишь окно рабочего стола (class='Progman', text='Program Manager') если оно равно активному окну, то гасишь свое окно и ставишь иконку в трей. При клике на иконке убираешь ее из трея и показываешь свое окно.
Как-то так: http://rghost.ru/35859064 (без иконки в трее)
Как-то так: http://rghost.ru/35859064 (без иконки в трее)
Dimas
(11.01.2012 в 19:07):
Интересный вариант, можно попробовать
А вот такой вопрос - никогда не приходилось решать такое - сворачивание проги в трей при активации рабочего стола ? (а-ля total commander)
Как-то пробовал гуглить данный вопрос для Дельфей, но чет путнего ничего не нашел...
А вот такой вопрос - никогда не приходилось решать такое - сворачивание проги в трей при активации рабочего стола ? (а-ля total commander)
Как-то пробовал гуглить данный вопрос для Дельфей, но чет путнего ничего не нашел...
Добавить комментарий
Заполните форму для добавления комментария
Пример программы с исходным текстом (FASM)
И чтобы программа в трее искала только их=)