Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2011.09.18;
Скачать: [xml.tar.bz2];

Вниз

FWSysTrayInfo от Rouse   Найти похожие ветки 

 
Hint   (2011-02-22 17:36) [0]

Сегодня появилась задача получить список значков из области уведомлений. Нашел код  от Rouse:
http://rouse.drkb.ru/winapi.php

К сожалению, на Windows 7 код работал с ошибками:
1. Не отображались изображения у видимых значков. Причина в том, что для TImageList используется оригинальная нумерация, а индексы в W7 идут не по порядку (т. е. для трех элементов индексы могут быть 5, 7, 9, а не 0, 1, 2).
2. Не отображались скрытые значки. В W7 они находятся в отдельном окне (в отдельном списке). Т. е. надо получать еще один Handle и дополнительно читать из него.

Модифицированный модуль:
http://pastebin.com/vsa34NXq

Возможно, кому-нибудь пригодится.

P. S. На Windows 7 код не работает без прав администратора.


 
Hint   (2011-02-22 17:39) [1]

Загрузил файл с ошибкой :)
Надо заменить "and TBSTATE_HIDDEN" на "or TBSTATE_HIDDEN".
Исправленная версия:
http://pastebin.com/pLspXmxR


 
Rouse_ ©   (2011-02-22 20:30) [2]

Угу, спасибо, в следующем обновлении сайта поправлю.


 
Rouse_ ©   (2011-02-22 20:34) [3]

Кстати просьба - выложи модуль с измененным заголовком вверху указав там свои координаты.
По примеру вот этого: http://rouse.drkb.ru/components.php#fwiconex
Нам так сказать чужой славы не нужно :)


 
Hint   (2011-02-22 21:30) [4]

Забавно. Заработало без прав администратора :)

Код:
   // Выделяем в нем память под текстовый буффер
   pszTextBuffer := VirtualAllocEx(hProcess, nil, MAX_PATH,
     MEM_COMMIT or MEM_TOP_DOWN, PAGE_READWRITE);
   if pszTextBuffer <> nil then
   try
     // Выделяем в нем память под структуру TTBButtonInfo
     pButtonInfo := VirtualAllocEx(hProcess, nil, SizeOf(TTBButtonInfo),
       MEM_COMMIT or MEM_TOP_DOWN, PAGE_READWRITE);
     if GetLastError = 0 then
     try
       // Заполняем структуру
       ZeroMemory(@ButtonInfo, SizeOf(TTBButtonInfo));

GetLastError сообщает об ошибке ("вызывающая сторона не обладает всеми необходимыми правами доступа"), но функция VirtualAllocEx при этом возвращает адрес.
Заменил проверку GetLastError на проверку указателя, все заработало.
А GetLastError, как оказалось, возвращает ошибку после SetDebugPriv.

Последняя версия:
http://pastebin.com/UjM1nX9D

Если не против, то я поменял версию с 1.00 на 1.01 и добавил про поддержку Windows 7.


 
Rouse_ ©   (2011-02-22 21:42) [5]

Да конечно - не вопрос


 
Hint   (2011-03-04 16:20) [6]

Утечка всплыла.

         hImageList := SHGetFileInfo(PChar(FIconData.Items[I].szAppPath),
           0, SHFileInfo, SizeOf(TSHFileInfo), SHGFI_SYSICONINDEX or SHGFI_SMALLICON);
         ImageList_ReplaceIcon(hImageList, SHFileInfo.iIcon, NprivIcon.hIcon);
         ImageList_ReplaceIcon(FIconData.ImageList.Handle, FIconData.Items[I].iImage,
           ImageList_GetIcon(hImageList, SHFileInfo.iIcon, ILD_NORMAL));

Не освобождается значок, полученный через ImageList_GetIcon.


 
Anatoly Podgoretsky ©   (2011-03-04 16:41) [7]

> Hint  (04.03.2011 16:20:06)  [6]

Значок какого цвета?


 
Hint   (2011-03-04 16:45) [8]


> Значок какого цвета?

Обычно зеленого, но иногда попадаются желтые. А что?


 
clickmaker ©   (2011-03-04 16:46) [9]

видимо, через желтые утекает


 
Rouse_ ©   (2011-03-04 17:01) [10]

Да скорее всего, чуть попозже гляну - еще руки не дошли до твоих правок.


 
Rouse_ ©   (2011-03-21 20:59) [11]

Обновил на сайте - проверяй...
http://rouse.drkb.ru/winapi.php#fwsystrayinfo


 
dimajest   (2011-05-26 03:47) [12]

Rouse_

DoGetIconsInfo
В случае использования 32 битного приложения с ключем IMAGE_FILE_LARGE_ADDRESS_AWARE в 64 битной среде имеем вылет оболочки.
В связи с тем, что выделение памяти происходит по правилу 4GB (приложения), а оболочка без этого ключа не может адресовать память выделеную с ключем MEM_TOP_DOWN (то есть последний мегабайт для приложения и оболочки - находятся в разной области памяти).

Спасибо за хороший класс.


 
Rouse_ ©   (2011-05-26 10:46) [13]

Не на чем проверить - 64 бит под рукой к сожалению нет.


 
Rouse_ ©   (2011-05-30 17:43) [14]


> dimajest   (26.05.11 03:47) [12]

Поковырялись на пару с Денисом, выложил новый вариант компонента. Можешь качать версию 1.03


 
Kerk ©   (2011-05-30 17:53) [15]

Годы идут, но вопрос "как запуздырить иконку в трей" все еще актуален :)


 
Rouse_ ©   (2011-05-30 19:24) [16]

Не Ромыч, тут задача как раз "как ее оттедова выпуздырить" :)
Вот Денис (harisma) например использует след образом: при старте своего приложения проверяет как был завершен предыдущий экземпляр приложения. Если аварийно, то при помощи данного класса ищет икону от старого экземпляра и удаляет ее :)


 
Юрий Зотов ©   (2011-05-30 22:52) [17]


> Rouse_ ©   (30.05.11 19:24) [16]

Хотя это должна была бы делать сама оболочка.
:o)


 
Inovet ©   (2011-05-30 22:57) [18]

Чьему перу принадлежит нетленное "запуздырить". Я первый раз вроде бы услышал в начале 1990-х в мульте "Чип и Дейл спешат на помощь", в той серии всему населению некая секта газировки запуздыривала мозг, а может и запузыривала, не помню, как там перевели.


 
Rouse_ ©   (2011-05-30 23:07) [19]


> Юрий Зотов ©   (30.05.11 22:52) [17]
> Хотя это должна была бы делать сама оболочка.

Юрч, ты глубоко заблуждаешся :) Оболочка удаляет инвалидную икону только когда с ней пользователь производит манипуляции (мышкой на ней провел, кликнул там не осторожно и т.д.). Собственно в этом и цимус ;)


 
Юрий Зотов ©   (2011-05-30 23:16) [20]


> Rouse_ ©   (30.05.11 23:07) [19]

Нет, Саша, это ты глубоко заблуждаешься. Или невнимательно читаешь. Я не хуже тебя знаю, когда оболочка УДАЛЯЕТ иконку, но говорил не об этом, а о том, когда она ДОЛЖНА была бы ее удалять.

Исчезло окно, принимающее сообщения от иконки - исчезла и сама иконка. Вот ТАК было бы правильно. И отслеживать это должна именно САМА оболочка.


 
Германн ©   (2011-05-31 00:27) [21]


>  Оболочка удаляет инвалидную икону только когда с ней пользователь
> производит манипуляции (мышкой на ней провел, кликнул там
> не осторожно и т.д.).

А я то думал, что это глюк моей программы.


 
Ega23 ©   (2011-05-31 10:08) [22]


> А я то думал, что это глюк моей программы.


Не. Попробуй через таск манагер процессы поприбивать. А иконки в трее останутся, пока мышой не проведёшь.


> Исчезло окно, принимающее сообщения от иконки - исчезла
> и сама иконка. Вот ТАК было бы правильно. И отслеживать
> это должна именно САМА оболочка.


Было бы совсем хорошо, если бы эта оболочка ещё дом сторожила, щи готовила и пиво подносила (правильной температуры). Но, к сожалению, таких совершенных систем пока не существует.


 
Rouse_ ©   (2011-05-31 10:20) [23]


> а о том, когда она ДОЛЖНА была бы ее удалять

А, понятно, только дело в том, что даже если окно исчезло, это никак не помешает мне переназначить _TNPRIVICON.hWnd на другое окно. Мошт на это и закладывались, мол негоже рубить сразу под корень? :)


 
Юрий Зотов ©   (2011-05-31 11:02) [24]


> Германн ©   (31.05.11 00:27) [21]

Видимо, это все же глюк программы - не посылаешь NIM_DELETE. Попробуй такую структуру кода:

if Shell_NotifyIcon(NIM_ADD, ...) then
try
 ...  
finally
  Shell_NotifyIcon(NIM_DELETE, ...)
end;

Иконка удаляется нормально, даже при аварийном завершении. Причем без всяких ректальных мероприятий.

> Ega23 ©   (31.05.11 10:08) [22]
> Было бы совсем хорошо, если бы эта оболочка ещё дом сторожила, щи
> готовила и пиво подносила (правильной температуры). Но, к сожалению,
> таких совершенных систем пока не существует.

Олег, что с тобой? Это же демагогия в чистом виде. Раньше ты такие "приемы" себе не позволял.

Речь не идет о том, чего оболочка не может и не должна делать. И даже о чем-то сложном речь не идет. Речь идет о простой операции, которую, оболочка вполне спокойно может и должна делать (кстати, и делает - только не тогда, когда надо).

> Rouse_ ©   (31.05.11 10:20) [23]
> даже если окно исчезло, это никак не помешает мне переназначить
> _TNPRIVICON.hWnd на другое окно.
</ I>
Так вот и будь добр СНАЧАЛА переназначить, а уж ПОТОМ убивай старое окно. Хоть сто порций.

А показывать невалидную иконку - некошерно, потому что это дезориентация юзера. Юзер видит иконку и думает, что программа нормально работает - а она на самом деле давно отвалилась и только одна иконка от нее осталась. Причем юзер совершенно не обязан каждую минуту проводить мышкой по иконкам, чтобы проверить, работают ли они.
I>
> Мошт на это и закладывались

Мошт. Но слабо верится.


 
Ega23 ©   (2011-05-31 11:17) [25]


> Речь идет о простой операции, которую, оболочка вполне спокойно
> может и должна делать (кстати, и делает - только не тогда,
>  когда надо).


Да чёрт его знает. Это как с"автоматическим обновлением данных у пользователя в гриде, когда другой юзверь данные как-то изменил.
можно регулярно рефрешить набор данных. Можно прикрутить событийный механизм. А можно отдать это дело пользователю - обновил тогда, когда сам захотел.
Последний вариант из трёх наименее эстетичен для искушённого пользователя, зато и наименьшую нагрузку даёт.
Вот, ИМХО, примерно то же самое и здесь.


 
Юрий Зотов ©   (2011-05-31 11:47) [26]

> Ega23 ©   (31.05.11 11:17) [25]
> Вот, ИМХО, примерно то же самое и здесь.

Не-а, далеко не  то же самое.

Сколько раз в минуту будет срабатывать автоматическая обновлялка данных при 1000 клиентских мест? Наверное, далеко не один. И каждый раз через сетку будет прокачиваться куча данных, а на каждом клиенте будет обновляться куча контролов. Накладно получается.

Кроме того, каково будет работать юзеру? Вот он набивает текст в каком-нибудь DB-контроле. Вдруг - хлоп! - вся его набивка исчезла и в этом контроле появился совсем другой текст. И юзер должен начинать набивку своего текста заново. Он набивает - а текст снова исчез и снова появился другой. И снова все сначала - сказка про белого бычка. Ты представляешь, что скажет юзер после 20-й неудачной попытки ввести в БД свой текст?

А в нашем случае что имеем? Одноразовую операцию без всякого трафика  и с обновлением только одного окна. И без напряга юзера. Кстати, еще и с освобождением неиспользуемых системных ресурсов, пусть даже и малых.

Когда убивается окно, система по-любому об этом событии знает. Привязка окон к иконкам ей тоже известна. Поэтому никто не мешает в момент убиения окна проверить, не завязан ли его хэндл на иконки - и если завязан, то такие иконки удалить. Накладных расходов - практически нет. И юзеру вполне себе комфортно.


 
Германн ©   (2011-06-01 01:28) [27]


> Юрий Зотов ©   (31.05.11 11:02) [24]
>
>
> > Германн ©   (31.05.11 00:27) [21]
>
> Видимо, это все же глюк программы - не посылаешь NIM_DELETE.
>  Попробуй такую структуру кода:
>
> if Shell_NotifyIcon(NIM_ADD, ...) then
> try
>  ...  
> finally
>   Shell_NotifyIcon(NIM_DELETE, ...)
> end;
>
> Иконка удаляется нормально, даже при аварийном завершении.
>  Причем без всяких ректальных мероприятий.
>

Хм. А как мне в блок try-finally запихать всю программу?


 
Ega23 ©   (2011-06-01 02:04) [28]


> Иконка удаляется нормально, даже при аварийном завершении.


А если извне процесс убить? Не "завершение приложение", а именно процесс грохнуть?



Страницы: 1 вся ветка

Форум: "Прочее";
Текущий архив: 2011.09.18;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.53 MB
Время: 0.003 c
15-1306268993
Юрий
2011-05-25 00:29
2011.09.18
С днем рождения ! 25 мая 2011 среда


15-1306253551
Чайник
2011-05-24 20:12
2011.09.18
Удаление файла


2-1306852612
MenuItem.Bitmap
2011-05-31 18:36
2011.09.18
Динамически поменять Bitmap у элемента TMenuItem


15-1306308339
NailMan
2011-05-25 11:25
2011.09.18
Давно что то не летали(акро-видео)


15-1298385410
Hint
2011-02-22 17:36
2011.09.18
FWSysTrayInfo от Rouse





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский