Конференция "KOL" » Отсутствие пиктограммы в SysTray.
 
  • AndreyRus © (10.07.13 18:01) [0]
    Долго наблюдал и никак не мог понять куда пропадает иконка в 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".
  • Vladimir Kladov © (19.07.13 23:04) [1]
    Разве не лучше сразу использовать AutoRecreate := TRUE; ? Это позволит избавить от проблем при аварийном завершении проводника, что все-таки иногда случается даже в новых версиях Windows. (Или это не помогает при старте? Поправьте, если что).
  • AndreyRus © (22.07.13 11:52) [2]
    AutoRecreate := TRUE; не поможет при старте OS. Единственная возможность - контроль возвращаемого значения Shell_NotifyIcon. Информацию "подчерпнул" из http://www.rsdn.ru/forum/winapi/4985210.flat
  • AndreyRus © (22.07.13 11:56) [3]
    Создаю так:
    Icon := NewTrayIcon(Applet, LoadImgIcon('MAINICON', 16));
    Icon.AutoRecreate := True;



    С моим предложенным вариантом изменения KOL.pas работает без нареканий.
  • Vladimir Kladov © (22.07.13 16:45) [4]
    Мне это решение не нравится.
    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 был бы не таким, как сейчас.

    И мне не нравится этот вечный цикл. Вдруг случится так, что по неведомой причине иконка в трее так и не сможет проявиться. Например, по причине отсутствия трея. Не все программы, желающие иметь иконку в трее, живут только в нем одном, и смогли бы на худой конец обойтись и без него, если что.
  • AndreyRus © (22.07.13 20:03) [5]
    > Но... XP умирает, и с вероятностью 99% проблема и так не проявится в будущем. (Под win7 проблема есть или нет? я не допонял).

    У меня есть одна довольно популярная программка на KOL. Практически с первого релиза получаю от пользователей претензии, что программа видна в процессах, а иконки нет. Я лично протестировал от XP до 8 и был весьма расстроен наблюдая сей баг своими глазами в OS - XP, Vista, 7, 8.
  • Rouse_ © (22.07.13 20:14) [6]
    Очень странная проблема, за всю свою практику ошибка вызова Shell_NotifyIcon + NIM_ADD встречалась раза два от силы.
    Единственная штатная ситуация исчезновения иконки - пересоздание эксплорера, но для этого достаточно подписаться на соответствующее сообщение.
    Есть еще один вариант исчезновения иконки из трея - это неверная обработка оконных сообщений от самой иконки (тогда да - она может пропасть).
    Здесь скорее третий вариант.
  • AndreyRus © (22.07.13 20:16) [7]
    > И мне не нравится этот вечный цикл.

    Аналогично, но как показали многочисленные испытания проблем он не создает.
  • Rouse_ © (22.07.13 20:19) [8]
    ЗЫ: если исключить влияние VCL или KOL вот это приложение, реализованное на АПИ, никогда не страдало такого плана "глюками", поэтому проблема явно наведенная...
    http://rouse.drkb.ru/winapi.php#wndinfo
  • AndreyRus © (22.07.13 20:29) [9]
    > Rouse_
    > Очень странная проблема, за всю свою практику ошибка вызова
    > Shell_NotifyIcon + NIM_ADD встречалась раза два от силы.

    Странно, я много раз замечал этот эффект, как на своих программах на KOL, так и, что самое главное, на сторонних продуктах. Причем, как я заметил, это не связанно с тем, как многие считают - "При старте одновременно загружается много тяжелых приложений". Скорее наоборот, этот баг чаще проявляется на маленьких и быстрых программах, которые загрузились раньше эксплорера и пытаются создать в нем иконку.
  • AndreyRus © (22.07.13 20:46) [10]
    > Rouse_
    Попробуй позапускать эту программу на API автоматически из "планировщика заданий", как собственно это и рекомендует Microsoft.
  • Rouse_ © (23.07.13 01:03) [11]

    > AndreyRus ©   (22.07.13 20:46) [10]

    Ок попробую...
  • Vladimir Kladov © (23.07.13 17:09) [12]
    Я ставил флажок "Автозапуск при старте системы" в настройках самой программы. Пока не видел этого флажка, один раз поставил ярлык в автозагрузки. Пробовал под 7 и под живой XP (на работе еще есть такие). Не пропадает. На XP под виртуалкой тоже не пропадает.

    Вариантов, почему у меня эффект не проявился, море. От наличие в системе антивирусов (на одном KAS, на другом Avira, на третьем MS Essencials), какого-то еще софта, входа в систему с паролем до тонкой настройки какими-нибудь твикерами (или наоборот, ручной оптимизацией служб, которую я всегда провожу на используемых системах, а в 7 - еще и планировщика). Может, в моем случае системы просто меньше тормозят, и запуск оболочки происходит быстрее, не знаю. Но с этой программой мне не повезло, эффект не проявился.
  • AndreyRus © (23.07.13 19:21) [13]
    У меня в XML использующемся для автозапуска программы, есть два параметра, которые, увеличивают шанс обнаружения данного бага:

    1. <RunLevel>HighestAvailable</RunLevel>
    2. <Priority>0</Priority>

    Первый предполагает запуск с повышенными правами, второй увеличивает приоритет процесса до максимально возможного (по умолчанию программы запускаемые из планировщика получают низкий уровень приоритета процесса).
  • Vladimir Kladov © (23.07.13 20:57) [14]
    А разве XML для планировщика доступен в XP? Ну, и если на то пошло, хотелось бы увидеть весь xml-файл. Есть вероятность, что проблема решается совсем другим способом (правильным выставлением опций в XML).
  • AndreyRus © (24.07.13 12:12) [15]
    Ув. Владимир! Пожалуйста, не тратьте свое драгоценное время на моделирование этой ошибки. Используйте мой опыт - функцию Shell_NotifyIcon нельзя использовать как процедуру.
  • Vladimir Kladov © (24.07.13 15:34) [16]
    Я просто пытаюсь добраться до сути. В чем смысл Вашего решения: главный поток (или единственный?) замораживается до появления возможности установки иконки в трей. Зачем тогда вообще торопиться запускать программу до окончательного входа в систему?

    На самом деле, я уже сделал и испробовал исправление, о котором уже говорил. Результат присваивания Active := TRUE - иконка пытается установиться, если не получилось, Active остается FALSE. После чего можно сделать цикл с ожиданием, пока не получится TRUE, в том числе предусмотреть предельный период, после которого можно отказаться от попыток и просто показать форму, чтобы вообще не остаться без интерфейса (например). Но вечный цикл в самом присваивании значения Active не возникнет никогда, даже если роль оболочки исполняет не explorer, и у этой оболочки нет трея. С обновлением будет.
  • AndreyRus © (24.07.13 15:51) [17]
    Спасибо! В ASM версии это тоже будет реализовано?
  • Vladimir Kladov © (24.07.13 16:21) [18]
    Разумеется. Постараюсь на неделе выложить.
  • AndreyRus © (03.08.13 02:11) [19]
    Начиная с версии 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;
 
Конференция "KOL" » Отсутствие пиктограммы в SysTray.
Есть новые Нет новых   [118232   +42][b:0][p:0.001]