-
Долго наблюдал и никак не мог понять куда пропадает иконка в SysTray в программе стартующей вместе с OS. Пробовал разные костыли, но полностью избавится от этого эффекта оказалось возможным только модификацией KOL.pas Для этого необходимо "обернуть" строку Shell_NotifyIcon следующим кодом: if (V = NIM_ADD) and (AutoRecreate = False) then
while not Shell_NotifyIcon( V, @NID ) do Sleep(100)
else
Shell_NotifyIcon( V, @NID ); Данная "обертка" была многократно проверена на различных OS и показала себя прекрасно. Желающие повторить эту модификацию - не забудьте включить директиву "PAS_VERSION".
-
Разве не лучше сразу использовать AutoRecreate := TRUE; ? Это позволит избавить от проблем при аварийном завершении проводника, что все-таки иногда случается даже в новых версиях Windows. (Или это не помогает при старте? Поправьте, если что).
-
-
Создаю так: Icon := NewTrayIcon(Applet, LoadImgIcon('MAINICON', 16));
Icon.AutoRecreate := True; С моим предложенным вариантом изменения KOL.pas работает без нареканий.
-
Мне это решение не нравится. 1) Есть вечный цикл, пусть и засыпанием, но может ведь и не проснуться. 2) Тред я прочитал. Но не понял, как ситуацию повторить.У меня есть автостартующие приложения с треем (часы, мультиклиборд), но не было случая их непоявления. И, наверное, уже не будет такого случая, т.к. XP у меня теперь живет только на виртуалках. И левые сборки я не использую. И кучу хлама для установки в трей у меня не присутствует. И гибернацией я пользуюсь чаще (причем, теперь на уровне хостовой ос, 7 или 8).
Поэтому хотелось бы другое решение для "проблемы", которую не всякий встретит на своем пути. Как быстрое решение, можно окружить новую часть кода {$IFDEF FORCE_TRAYICON_ONSTART} (например) как обычно. (Или наоборот, закомментарить добавку при условии SMALLER_CODE).
Более мягкий вариант: при вызове Shell_Notifyicon результат складывается в поле FActive (при успешном удалении иконки туда, наоборот, записывается FALSE). И тогда нужный цикл с нужной задержкой хоть в 5000, хоть в 10 можно поставить снаружи. Мне кажется, такой вариант был бы лучшим. Можно добавить метод ForceActivate, который бы организовал такой цикл с присваиванием Active := TRUE пока он не станет TRUE. С задержками, таймаутом - для тех, кто получил означенную проблему.
Я ПОНИМАЮ, что Ваш вариант лучше уже потому, что в нем у программиста голова никогда не будет болеть, и он просто с вероятностью 99% с проблемой даже и не столкнется, а лишние 100 байт кода не стоят даже моих этих рассуждений.
Но... XP умирает, и с вероятностью 99% проблема и так не проявится в будущем. (Под win7 проблема есть или нет? я не допонял). Что бы Вы сами выбрали? И если так всегда рассуждать - "давайте добавим кода и решим проблему за кривую ОС, раз уж программисты в МС облажались" - так и KOL был бы не таким, как сейчас.
И мне не нравится этот вечный цикл. Вдруг случится так, что по неведомой причине иконка в трее так и не сможет проявиться. Например, по причине отсутствия трея. Не все программы, желающие иметь иконку в трее, живут только в нем одном, и смогли бы на худой конец обойтись и без него, если что.
-
> Но... XP умирает, и с вероятностью 99% проблема и так не проявится в будущем. (Под win7 проблема есть или нет? я не допонял).
У меня есть одна довольно популярная программка на KOL. Практически с первого релиза получаю от пользователей претензии, что программа видна в процессах, а иконки нет. Я лично протестировал от XP до 8 и был весьма расстроен наблюдая сей баг своими глазами в OS - XP, Vista, 7, 8.
-
Очень странная проблема, за всю свою практику ошибка вызова Shell_NotifyIcon + NIM_ADD встречалась раза два от силы. Единственная штатная ситуация исчезновения иконки - пересоздание эксплорера, но для этого достаточно подписаться на соответствующее сообщение. Есть еще один вариант исчезновения иконки из трея - это неверная обработка оконных сообщений от самой иконки (тогда да - она может пропасть). Здесь скорее третий вариант.
-
> И мне не нравится этот вечный цикл.
Аналогично, но как показали многочисленные испытания проблем он не создает.
-
ЗЫ: если исключить влияние VCL или KOL вот это приложение, реализованное на АПИ, никогда не страдало такого плана "глюками", поэтому проблема явно наведенная... http://rouse.drkb.ru/winapi.php#wndinfo
-
> Rouse_ > Очень странная проблема, за всю свою практику ошибка вызова > Shell_NotifyIcon + NIM_ADD встречалась раза два от силы.
Странно, я много раз замечал этот эффект, как на своих программах на KOL, так и, что самое главное, на сторонних продуктах. Причем, как я заметил, это не связанно с тем, как многие считают - "При старте одновременно загружается много тяжелых приложений". Скорее наоборот, этот баг чаще проявляется на маленьких и быстрых программах, которые загрузились раньше эксплорера и пытаются создать в нем иконку.
-
> Rouse_ Попробуй позапускать эту программу на API автоматически из "планировщика заданий", как собственно это и рекомендует Microsoft.
-
> AndreyRus © (22.07.13 20:46) [10]
Ок попробую...
-
Я ставил флажок "Автозапуск при старте системы" в настройках самой программы. Пока не видел этого флажка, один раз поставил ярлык в автозагрузки. Пробовал под 7 и под живой XP (на работе еще есть такие). Не пропадает. На XP под виртуалкой тоже не пропадает.
Вариантов, почему у меня эффект не проявился, море. От наличие в системе антивирусов (на одном KAS, на другом Avira, на третьем MS Essencials), какого-то еще софта, входа в систему с паролем до тонкой настройки какими-нибудь твикерами (или наоборот, ручной оптимизацией служб, которую я всегда провожу на используемых системах, а в 7 - еще и планировщика). Может, в моем случае системы просто меньше тормозят, и запуск оболочки происходит быстрее, не знаю. Но с этой программой мне не повезло, эффект не проявился.
-
У меня в XML использующемся для автозапуска программы, есть два параметра, которые, увеличивают шанс обнаружения данного бага:
1. <RunLevel>HighestAvailable</RunLevel> 2. <Priority>0</Priority>
Первый предполагает запуск с повышенными правами, второй увеличивает приоритет процесса до максимально возможного (по умолчанию программы запускаемые из планировщика получают низкий уровень приоритета процесса).
-
А разве XML для планировщика доступен в XP? Ну, и если на то пошло, хотелось бы увидеть весь xml-файл. Есть вероятность, что проблема решается совсем другим способом (правильным выставлением опций в XML).
-
Ув. Владимир! Пожалуйста, не тратьте свое драгоценное время на моделирование этой ошибки. Используйте мой опыт - функцию Shell_NotifyIcon нельзя использовать как процедуру.
-
Я просто пытаюсь добраться до сути. В чем смысл Вашего решения: главный поток (или единственный?) замораживается до появления возможности установки иконки в трей. Зачем тогда вообще торопиться запускать программу до окончательного входа в систему?
На самом деле, я уже сделал и испробовал исправление, о котором уже говорил. Результат присваивания Active := TRUE - иконка пытается установиться, если не получилось, Active остается FALSE. После чего можно сделать цикл с ожиданием, пока не получится TRUE, в том числе предусмотреть предельный период, после которого можно отказаться от попыток и просто показать форму, чтобы вообще не остаться без интерфейса (например). Но вечный цикл в самом присваивании значения Active не возникнет никогда, даже если роль оболочки исполняет не explorer, и у этой оболочки нет трея. С обновлением будет.
-
Спасибо! В ASM версии это тоже будет реализовано?
-
Разумеется. Постараюсь на неделе выложить.
-
Начиная с версии KOL 3.20 для решения этой проблемы следует использовать нижеследующий код:
Icon := NewTrayIcon(Applet, HICON); if not Icon.Active then Icon.ForceActive(100, 10000); if not Icon.Active then begin MsgOK('Not find the Explorer!'); Halt; end;
|