![]() |
Модераторы: Snowy, MetalFan, bems, Poseidon |
![]() ![]() ![]() |
|
MetalFan |
|
|||
![]() Аццкий Сотона ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3815 Регистрация: 2.10.2006 Где: Moscow Репутация: 22 Всего: 128 |
Простите за заголовок темы, вроде как все должно быть просто...
Но возникла небольшая сложность, что-то не соображу, как правильно победить. Цель: Сворачивать приложение в трей (+убирать из панели задач) , по щелчку по иконке - разворачивать (возвращать в панель задач) Компоненты (Delphi XE): TTrayIcon, TApplicationEvents. Первому назначен OnClick, второму OnMinimize/OnRestore Код :
в аттаче тестовое приложение с указанным кодом. Проблема: на первый взгляд все хорошо: сворачиваем - получаем иконку в трее, разворачиваем - получаем приложение в панели задач... Но! При сворачивании по клику по кнопке в панели задач приложение обратно из трея не разворачивается( Городил собственную обработку сворачивания/разворачивания (вместо Application.Minimize/Restore), но там другие косяки повылазили... Может кто сталкивался и знает изящное решение? Всем спасибо за внимание, wbw, MetalFan. Это сообщение отредактировал(а) MetalFan - 1.5.2011, 17:59 Присоединённый файл ( Кол-во скачиваний: 23 ) ![]() -------------------- There are always someone smarter than you... |
|||
|
||||
Rrader |
|
|||
Inspired =) ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 1535 Регистрация: 7.5.2005 Репутация: 18 Всего: 191 |
Как увиделось, проблема в том, что IsIconic работает по-разному в разных случаях сворачивания. А что, если зафорсить единое поведение?
|
|||
|
||||
MetalFan |
|
|||
![]() Аццкий Сотона ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3815 Регистрация: 2.10.2006 Где: Moscow Репутация: 22 Всего: 128 |
Rrader, Да, на IsIconic тоже обратил внимание... почему-то IsIconic "слетает" после того, как Hide форме делается...
А SC_MINIMIZE приходит до вызова Application.OnMinimize (точнее как раз OnMinimize вызывается вследствие прихода SC_MINIMIZE) судя по коду TApplication.WndProc... Но твой вариант работает верно... спасибо за идею) Может вообще есть более корректный подход, чем который я изначально привел? кстати, IsIconic возвращает неверно выставленный внутренний флаг TApplication.FAppIsIconic в моем случае... который выставляется по приходу WM_ACTIVATEAPP, после того, как приложение свернуто... хм. косяк что-ли где-то в VCL. Это сообщение отредактировал(а) MetalFan - 1.5.2011, 18:52 -------------------- There are always someone smarter than you... |
|||
|
||||
MetalFan |
|
||||
![]() Аццкий Сотона ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3815 Регистрация: 2.10.2006 Где: Moscow Репутация: 22 Всего: 128 |
Подниму сию тему...
В общем решил исходную задачу следующим рабочим кодом, который прекрасно отрабатывает по клику на иконку в трее (используется стандартный компонент - TTrayIcon):
Данный код сворачивает приложение "в трей", если оно "развернуто", либо разворачивает его из оного, если оно было свернуто. Иконка в трее теперь видна всегда. Задача: модифицировать код так, чтобы при вызове этого кода в момент клика мышью на иконке в трее добавился третий вариант реакции - если приложение развернуто, но не на переднем плане, перенести его на передний план... Казалось бы, что сложного, во вторую ветку добавить проверку вида
Но в момент клика на иконку в трее, при вызове данного кода, GetForegroundWindow всегда <> Self.Handle Другие, пришедшие в голову проверки (GetTopWindow, Application.Active, Applicaiton.MainForm.Active, etc...) так же не срабатывают, т.к. в момент клика активным окном на переднем плане становится окно тулбара винды... Собственно уважаемые коллеги, какие будут соображения на эту тему? p.s.По скольку вопрос напрямую связан с сабжевым вопросом, то создавать новую тему не вижу смысла Это сообщение отредактировал(а) MetalFan - 12.1.2012, 08:07 -------------------- There are always someone smarter than you... |
||||
|
|||||
Чучмек |
|
|||
НЭТ БИЛЭТ ![]() ![]() Профиль Группа: Участник Сообщений: 841 Регистрация: 11.5.2008 Где: СССР Репутация: 7 Всего: 41 |
-------------------- умную мысль держи при себе, а дурной - поделись с другими |
|||
|
||||
CodeMonkey |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1839 Регистрация: 24.6.2008 Где: Россия, Тверь Репутация: 29 Всего: 89 |
Это баг в Delphi.
Application.Restore первым делом проверяет "свёрнутость" окна. Проблема в том, что делает она это на Handle себя, а не формы (это при MainFormOnTaskbar = True). Application.Handle и Application.MainForm.Handle - это два разных окна и их состояния могут быть несогласованными, что мы и получаем в этом примере. Решение: сворачивать Application.
Добавлено через 2 минуты и 34 секунды P.S. Эх, проморгал исходную тему, а то сохранил бы тебе полгода мучений ![]() -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. |
|||
|
||||
CodeMonkey |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1839 Регистрация: 24.6.2008 Где: Россия, Тверь Репутация: 29 Всего: 89 |
Чего-то слона-то я и не заметил... Не очень понял как может быть "если приложение развернуто, но не на переднем плане" одновременно с "при клике мышью на иконке в трее". Ты же скрываешь икноку при показе окна. В любом случае проверка должна опираться на видимость окна. Видимо окно - на первый план его, нет - восстановить. -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. |
|||
|
||||
MetalFan |
|
|||
![]() Аццкий Сотона ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3815 Регистрация: 2.10.2006 Где: Moscow Репутация: 22 Всего: 128 |
по делу есть что сказать? В том то и дело, что рассматриваем вариант, когда иконка в трее видна всегда. Предложенный второй отрезок кода при его вызове работает так: Если приложение свернуто - разворачивает, если развернуто, то сворачивает... Необходимо модифицировать: Если приложение НЕ свернуто в трей, но, к примеру, сейчас активно окно другого приложения, то в этом случае наше приложение должно "переехать" на передний план, а не свернуться в трей, при клике по его иконке в этом трее. Такое поведение наблюдается, к примеру, у The Ваt при соответствующих настройках. Исходный же алгоритм ВСЕГДА сворачивает приложение, если оно не свернуто. В итоге задача сводится к тому, что как в момент клика на иконке в трее определить, что ДО клика было активно окно нашего приложения. Это сообщение отредактировал(а) MetalFan - 12.1.2012, 08:04 -------------------- There are always someone smarter than you... |
|||
|
||||
CodeMonkey |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1839 Регистрация: 24.6.2008 Где: Россия, Тверь Репутация: 29 Всего: 89 |
А, всё, понял.
Это просто: возьми Foreground или Active окно (надо проверить, как там с SOT-окнами), найди следующее по Z-порядку (GetNextWindow). Если твоё - то ты сверху, минимизируй. Если не твоё, то ты перекрыт - сворачивайся. -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. |
|||
|
||||
MetalFan |
|
|||
![]() Аццкий Сотона ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3815 Регистрация: 2.10.2006 Где: Moscow Репутация: 22 Всего: 128 |
CodeMonkey, не сработало) пробовал так уже. В момент клика, даже если перед этим было активно наше окно, то GetNextWindow от GetForegroundWindow возвращает вообще другое окно, никак не относящееся к нашему приложению.
з.ы. а что такое SOT-окна? Это сообщение отредактировал(а) MetalFan - 12.1.2012, 11:20 -------------------- There are always someone smarter than you... |
|||
|
||||
CodeMonkey |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1839 Регистрация: 24.6.2008 Где: Россия, Тверь Репутация: 29 Всего: 89 |
SOT = Stay On Top
Через Spy++ проверь, что там GetNextWindow возвращает. По нему же можно цепочку Z order проверить (вроде). -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. |
|||
|
||||
MetalFan |
|
|||
![]() Аццкий Сотона ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3815 Регистрация: 2.10.2006 Где: Moscow Репутация: 22 Всего: 128 |
CodeMonkey, вот моя пока нерабочая модификация кода:
Смотрел в S++, в момент нажатия по трею GetNextWindow(GetForegroundWindow, GW_HWNDNEXT) и GetNextWindow(GetForegroundWindow, GW_HWNDPREV) возвращает вообще левые окна... что и видно в S++. тестовое приложение в аттаче. Это сообщение отредактировал(а) MetalFan - 12.1.2012, 12:18 Присоединённый файл ( Кол-во скачиваний: 8 ) ![]() -------------------- There are always someone smarter than you... |
|||
|
||||
CodeMonkey |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1839 Регистрация: 24.6.2008 Где: Россия, Тверь Репутация: 29 Всего: 89 |
А что это за окна? Чьи они? И какие у них атрибуты? Добавлено через 1 минуту и 2 секунды Кстати, а ты пробовал GetLastActivePopup? -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. |
|||
|
||||
MetalFan |
|
|||
![]() Аццкий Сотона ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3815 Регистрация: 2.10.2006 Где: Moscow Репутация: 22 Всего: 128 |
просто окна других приложений. среди них нет моего. пробовал. Если в него отдаешь 0, то возвращается 0, если отдаешь хэндл формы, то получаешь тот же хэндл формы. -------------------- There are always someone smarter than you... |
|||
|
||||
Чучмек |
|
|||
НЭТ БИЛЭТ ![]() ![]() Профиль Группа: Участник Сообщений: 841 Регистрация: 11.5.2008 Где: СССР Репутация: 7 Всего: 41 |
OnPaint
-------------------- умную мысль держи при себе, а дурной - поделись с другими |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Delphi: Для новичков" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Delphi: Для новичков | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |