Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« : 17-07-2007 11:48 » |
|
столкнулся с пустяковым, однако некрасивым, глюком : имеется запущенный FireBird, в трее горит его иконка. Если программно убиваю процесс птицы, то иконка остаётся. Если запустить птицу снова - появляется новая иконка рядом со старой. В то же время, если провести мышью по трею, то ненужные иконки исчезнут. Как программно перерисовать трей ?
|
|
|
Записан
|
|
|
|
PooH
Глобальный модератор
Offline
Пол:
... и можно без хлеба!
|
|
« Ответ #1 : 17-07-2007 12:38 » |
|
Попробуй что-нибудь вроде ToolBar := FindWindow("Shell_TrayWnd", null); Tray := FindWindowEx(ToolBar, 0, "TrayNotifyWnd", null); UpdateWindow(Tray);
|
|
« Последнее редактирование: 17-07-2007 12:43 от PooH »
|
Записан
|
Удачного всем кодинга! -=x[PooH]x=-
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #2 : 17-07-2007 15:32 » |
|
PooH , пробовал так HWND hToolBar=::FindWindow("Shell_TrayWnd",0); if(!hToolBar || hToolBar==(HWND)-1) return;
HWND hTray=::FindWindowEx(hToolBar,0,"TrayNotifyWnd",0); if(!hTray || hTray==(HWND)-1) return;
::UpdateWindow(hTray);
hTray=::FindWindowEx - возвращает 0 ... также не помогает ::ShowWindow(hToolBar,SW_HIDE); ::ShowWindow(hToolBar,SW_SHOW);
полоса скрывается, потом появляется обратно - а значок в трее на месте. Проводим мышой - исчезает. Чёт тут другое надо...
|
|
|
Записан
|
|
|
|
Kivals
|
|
« Ответ #3 : 17-07-2007 15:47 » |
|
А ты мышкой программно поводи в трее А если серьезно - то API для трэя сильно недоработано, многие вещи в принципе невозможно сделать без выпендрежа... Да - можно пересоздать трей, но многие проги не ловят этого события - попропадают нужные иконки...
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #4 : 17-07-2007 17:23 » |
|
Kivals, весь бед в том, что надо мышью попасть по иконке ) Можно, конечно, при помощи ::SetCursorPos, провесли "черту" по всей полосе таскбара, но как учесть, что бар может быть где угодно на экране, а кроме того - иконки необязательно в одну линию могут быть, если бар увеличен по высоте
|
|
|
Записан
|
|
|
|
nikedeforest
|
|
« Ответ #5 : 17-07-2007 17:33 » |
|
Алексей, у меня такое часто бывает с другими приложениями. Так что забей.
|
|
|
Записан
|
ещё один вопрос ...
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #6 : 17-07-2007 17:35 » |
|
nikedeforest, между тем, Spy++ как-то находит хендл трея , и даже подсвечивает его при помощи команды Highlight
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #7 : 17-07-2007 18:19 » |
|
убедил я трея вот таким образом POINT pnSave;
//сохраняем положение курсора ::GetCursorPos(&pnSave);
HWND hToolBar=::FindWindow("Shell_TrayWnd",0); if(!hToolBar || hToolBar==(HWND)-1) return;
RECT rTB; if(!::GetWindowRect(hToolBar,&rTB))return;
//"сканируем" прямоугольник с сеткой 8*8 пикселов long x,y; long dx=8; long dy=8; for(y=rTB.top;y<=rTB.bottom;y+=dy) { for(x=rTB.left;x<=rTB.right;x+=dx) { ::SetCursorPos(x,y); mouse_event(MOUSEEVENTF_MOVE,0,0,0,0); //Sleep(10); } }
//восстанавливаем положение курсора ::SetCursorPos(pnSave.x,pnSave.y);
Если разремить слип после ::SetCursorPos(x,y); , то станет видно, как курсор бегает )
|
|
« Последнее редактирование: 17-07-2007 18:29 от Алексей1153++ »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #8 : 17-07-2007 18:33 » |
|
всё же хотелось бы прямоугольник только трея заполучить...
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #9 : 18-07-2007 04:52 » |
|
ещё одна проблема - не получаетсяотобразить в трее иконку 16*16 , отображается отмасштабированная 32*32 (естественно, покорёженная) Пока вышел из положения так - сделал ресурс иконки для трея, скопировал туда иконку 16*16 и растянул в 2 раза, то есть пикселы стали размером 2*2. Тогда при масштабировании получается аккуратная иконка
Но может можно заставить сразу 16*16 вариант иконки отобразить ?
|
|
|
Записан
|
|
|
|
PooH
Глобальный модератор
Offline
Пол:
... и можно без хлеба!
|
|
« Ответ #10 : 18-07-2007 05:15 » |
|
|
|
|
Записан
|
Удачного всем кодинга! -=x[PooH]x=-
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #11 : 18-07-2007 05:33 » |
|
ну с перерисовкой они точно так же поступили, как и я ) А про маленькую икону там нету...
|
|
|
Записан
|
|
|
|
Daniloff
Помогающий
Offline
|
|
« Ответ #12 : 19-07-2007 17:16 » |
|
было и такое... чтобы вставить маленькую икону, делал ее состоящей только из 16х16... а фантомные иконы - это глюки винды, если любую программу убить жестоко - они появляются. убивать надо нежно... Вот Radmin2 - тот еще параноик, если машинка притормаживает - штук 10 иконок в трей напихает...
|
|
|
Записан
|
|
|
|
Kivals
|
|
« Ответ #13 : 19-07-2007 20:26 » |
|
У меня выводило в трей иконку 16х16 (при том что этот ресурс содержал и 32х32), но не вспомню как - давно дело было... По-моему там заморочка еще и с количеством цветов была (правда я тогда на Вин2000 был, в ХР уже вроде полноцветные выводятся). Что касается прямоугольника трея: после HWND hToolBar=::FindWindow("Shell_TrayWnd",0); if(!hToolBar || hToolBar==(HWND)-1) return; добавь еще hToolBar=::FindWindowEx(hToolBar,0,'TrayNotifyWnd',0); if(!hToolBar || hToolBar==(HWND)-1) return;
|
|
|
Записан
|
|
|
|
Kivals
|
|
« Ответ #14 : 19-07-2007 20:55 » |
|
Перечитал внимательно ссылку от PooH - там ниже есть код который "честно" просматривает все иконки в трее на предмет наличия у них родительского процесса и правильно (Shell_NotifyIcon) убирает лишние. Ищи по function RefreshTray: Boolean; По отзывам (там же) - метод работает даже в Висте. (метод с шарканьем мышкой думаю оставит скрытые иконки, этот метод по идее убьет все лишние. На досуге проверю)
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #15 : 20-07-2007 03:25 » |
|
Kivals, прикинь, не могу понять прикола, я в постах выше писал, что пробовал HWND hToolBar=::FindWindow("Shell_TrayWnd",0); HWND hTray=::FindWindowEx(hToolBar,0,"TrayNotifyWnd",0);
и hTray оказывалось ==0 , а сейчас получилось, чё за нафик ? )) а за код спасибо, сейчас опробую
|
|
|
Записан
|
|
|
|
Kivals
|
|
« Ответ #16 : 21-07-2007 17:10 » |
|
А фиг его знает у них там (по ссылке) вообще 3 поиска: PrvWnd := FindWindow('Shell_TrayWnd', nil); PrvWnd := FindWindowEx(PrvWnd, 0, 'TrayNotifyWnd', nil); PrvWnd := FindWindowEx(PrvWnd, 0, 'ToolbarWindow32', nil); Так вот - если у меня есть 3-я строка, то GetWindowRect(PrvWnd, Rect) выдает ошибку
|
|
|
Записан
|
|
|
|
Daniloff
Помогающий
Offline
|
|
« Ответ #17 : 22-07-2007 05:28 » |
|
чего проще... взял Spy++ и уточнил.
Иерархия такова: Shell_TrayWnd()->TrayNotifyWnd()->SysPager()->ToolbarWindow32(Область уведомлений)
В win98 или МЕ может быть и по другому...
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #18 : 10-01-2008 07:14 » |
|
кстати, вернулся я что то к этой теме опять, нашёл, как именно хендл трея выцепить HWND hToolBar=::FindWindow("Shell_TrayWnd",0); if(hToolBar && hToolBar!=(HWND)-1) { HWND hTray=::FindWindowEx(hToolBar,0,"TrayNotifyWnd",0); if(hTray && hTray!=(HWND)-1) { ... } }
только ::UpdateWindow(hTray); - не чистит трей всё равно )))) Сябака. зато ::ShowWindow(hTray,SW_HIDE); - полный абзац )
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #19 : 10-01-2008 07:30 » |
|
такс, всё понятно, запутался в названиях классов. Теперь так: HWND hShell_TrayWnd=::FindWindow("Shell_TrayWnd",0); if(hShell_TrayWnd && hShell_TrayWnd!=(HWND)-1) { HWND hTrayNotifyWnd=::FindWindowEx(hShell_TrayWnd,0,"TrayNotifyWnd",0); if(hTrayNotifyWnd && hTrayNotifyWnd!=(HWND)-1) { HWND hSysPager=::FindWindowEx(hTrayNotifyWnd,0,"SysPager",0); if(hSysPager && hSysPager!=(HWND)-1) { HWND hToolBarWindow32=::FindWindowEx(hSysPager,0,"ToolBarWindow32",0); if(hToolBarWindow32 && hToolBarWindow32!=(HWND)-1) { ... } } } }
теперь hToolBarWindow32 - именно окошко с иконками. Как обновить, пока не нашёл )
|
|
|
Записан
|
|
|
|
zubr
Гость
|
|
« Ответ #20 : 10-01-2008 09:12 » |
|
Если тебе известен хендл окна убиваемого процесса, то почему не сделать Shell_NotifyIcon(NIM_DELETE, &data)?
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #21 : 10-01-2008 09:21 » |
|
zubr, а смотри какая сейчас ситуёвина Интегрирую свою программу с другой , которую не я делал. Та программа запускает мою , в трее висит значок. А если , скажем, убить процесс той программы (и все дочерние, то есть и мою тоже программу) , то иконка от моей останется в трее. Хендл неизвестен. Когда запускается всё по новой - уже две иконки , хотелось бы чистить в любой момент времени трей
|
|
|
Записан
|
|
|
|
zubr
Гость
|
|
« Ответ #22 : 10-01-2008 10:11 » |
|
Не совсем понял: 1. Если иконка твоя, то перед убийством другой программы, освобождай свою иконку. 2. Если иконка чужая, определяй хэндл окна чужой программы по заголовку, классу. В конце концов, раз чужая программа запускает твою, значит возможно сделать, чтобы хендл собственного окна она передавала через командную строку.
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #23 : 10-01-2008 10:43 » |
|
zubr, это всё понятно. Представь ситуацию: taskkill /im модуль /f /t - ну кто оттуда что и куда передаст ? А я заново запускаю программу вручную и хочу почистить трей
|
|
|
Записан
|
|
|
|
PooH
Глобальный модератор
Offline
Пол:
... и можно без хлеба!
|
|
« Ответ #24 : 10-01-2008 10:53 » |
|
))) задачу надо решать в корне, грохни и загрузи снова explorer.exe )))
|
|
|
Записан
|
Удачного всем кодинга! -=x[PooH]x=-
|
|
|
zubr
Гость
|
|
« Ответ #25 : 10-01-2008 10:56 » |
|
Тогда вообще непонятно зачем заморачиваться. Я думал ты из своей программы убиваешь процесс типа TerminateProcess, WM_DESTROY. А taskkill /im модуль /f /t - это некорректное завершение юзвером программы, поэтому на его совести, имхо.
|
|
|
Записан
|
|
|
|
PooH
Глобальный модератор
Offline
Пол:
... и можно без хлеба!
|
|
« Ответ #26 : 10-01-2008 10:59 » |
|
ну насколько я понял тут вопрос отдельной программы, которая апдейтит tray то есть, как раз для обновления трэя после некорректного завершения процеса.
|
|
|
Записан
|
Удачного всем кодинга! -=x[PooH]x=-
|
|
|
PooH
Глобальный модератор
Offline
Пол:
... и можно без хлеба!
|
|
« Ответ #27 : 10-01-2008 11:02 » |
|
вот тебе мега-батник taskkill /im explorer.exe /f explorer.exe хотя не факт, что сработает - могут "пропасть" иконки активных прог
|
|
« Последнее редактирование: 10-01-2008 11:05 от PooH »
|
Записан
|
Удачного всем кодинга! -=x[PooH]x=-
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #28 : 10-01-2008 11:06 » |
|
Я думал ты из своей программы убиваешь процесс типа TerminateProcess, WM_DESTROY.
это уже пройденная задача PooH, в принципе да, просто обновлялка для трея. То есть как-то надо безхозные иконки определить - может как-то можно перенумеровать их ?
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #29 : 10-01-2008 11:07 » |
|
вот тебе мега-батник
PooH, неет, такая жесть мне не нужна )
|
|
|
Записан
|
|
|
|
|