Форум: "Прочее";
Текущий архив: 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