[ baseQ @ 14.11.2008. 14:18 ] @
Pozdrav,
uradio sam app koja gasi odredjeni program (proces)
u nekom zadatom vremenu ili samo proverava (nije ni bitno),
cija se ikonica nalazi u system tray, pomeri
neke fajlove i opet startuje taj isti program, cija se
opet ikonica regularno pojavi u treju.
E sad vizuelno se ne refreshuje sam izgled desktopa
tj. samog s.tray tako da izgleda kao da se gomilaju
ikonice pored satica. Elem kada se predje misem
verovatno se triguje neki win event pa se refreshuje i nestanu
ne-validne.
Da li ima neka funkcija za sam refresh system tray-a.
Nemam neke velike zelje da googlujem.
Ako neko zna bio bih mu zahvalan,
poz
i unapred hvala.
[ mmix @ 14.11.2008. 15:21 ] @
Umesto sto na silu ubijas proces (sto i nije bas pozeljno) probaj da posaljes programu koji gasis poruku da se ugasi sam. Ako je program koji gasis dobro napisan pocistice sam za sobom i ikonica ce nestati sama.

[ baseQ @ 14.11.2008. 15:33 ] @
znaci goooooooooogluj ............
[ mmix @ 14.11.2008. 15:51 ] @
Nece ti to mnogo pomoci (sto naravno ne znaci da ne treba da googlujes :)), jedini za sada poznati nacin je lociranje prozora klase TrayNotifyWnd i otimanje kurzora misa korisniku i setanje istog iznad client area tog prozora i onda vracanje misa na poziciju sa koje je ukraden. U principu hack i simulacija korisnickog setanja misa iznad tray-a, googlaj za "TrayNotifyWnd" i naci ces neki sample.



[ baseQ @ 14.11.2008. 16:45 ] @
Da na zalost vec sam odradio ,
uuuuf sto mrzim da surfujem, ko iglu u plastu sena. vazda.
Ali
na msdn-u nadjoh slican problem
te je covek pomogao sa
Code:

//Include following code with yours to refresh System Tray.

public const int WM_PAINT = 0xF;
[DllImport("USER32.DLL")]
public static extern int SendMessage(IntPtr hwnd, int msg, int character, IntPtr lpsText);


//Send WM_PAINT Message to paint System Tray which will refresh it.
SendMessage(traynotifywnd,WM_PAINT,0,IntPtr.Zero);

Sad jos samo treba to malo prevesti i trebalo bi
da funkcionise. Videh da mu se zahvaljivao covek
pa nema smisla da sumnjam.

poz
[ mmix @ 14.11.2008. 19:36 ] @
Nazalost to znam jos od ranijeda, WM_PAIN ne reseava ovaj problem, on sam ponovo iscrta wintray prozor ali ne radi callback u aplikacije da vidi koja je jos ziva. (mozda win2008 i vista rade, to ne znam, ali na XP/2003 meni nije radilo)

Nadjoh taj tvoj post, pa procitaj malo nize:
Citat:
I tried this, but it doesn't work. That is, sending the WM_PAINT message to the traynotifywnd window doesn't make the icon (whose associated app was killed) go away.


[ baseQ @ 14.11.2008. 19:48 ] @
aj jaj jaj
taman sam hteo da se pozabavim kodom,
al bolje da si mi rekao nego da gubim vreme.

nista.....
trazim dalje........

poz
[ deerbeer @ 15.11.2008. 13:38 ] @
Da li si koristio ove funkcije
Update :
Code:

NOTIFYICONDATA    IconData;
Shell_NotifyIcon(NIM_MODIFY,&IconData);


Delete :
Code:

NOTIFYICONDATA    IconData;
Shell_NotifyIcon(NIM_DELETE,&IconData);


Mene nikad nije zezao tray sa ovim funkcijama , e sad mozda si nesto propustio ..
[ baseQ @ 15.11.2008. 22:24 ] @
Pokusao sam,
ne uspeva,
funkcija vraca gresku, a.k.a. povratna vrednost je 0.
a i ikone se gomilaju :)


pardon, pa i ne moze kad.
Joj, pa treba da prosledim HWND od app koju gasim :(((((((

uf hrkljus !
[ X Files @ 16.11.2008. 08:53 ] @
Letimičnim Google-ovanjem nisam pronašao neki automatizovan metod za refresh sistemskog tray-a. Izgleda da ne postoji. Ono što preostaje je simuliranje WM_MOUSEMOVE iznad regije tray-a, što će ukloniti mrtve ikone.

Ovde sam pronašao neki kod:
http://www.themssforum.com/MFC/Refresh-system/

@BaseQ
Koje razvojno okruženje koristiš? Da li beše BCB?
Ako da, evo koda koji sam delimično modifikovao (da radi kad je tray u vise linija) i prilagodio (neke casting konvencije) da se kompajlira i radi sa Borland C++ Builder okruženjem.

Ono što uočavam kao anomaliju ovog programa (originalni primer) je da on prolazi samo po jednoj horizontalnoj liniji po širini tray-a, očekujući da niko od korisnika nema tray u dva ili više redova, kao na primer ja. He he ;) Drugim rečima, ovaj kod neće raditi ako je tray ikona u drugom redu. Dalje, korak mu je jedan piksel, sto je verovatno isuvise sitno, ali nema veze. Brzo ce to raditi.

Evo koda:
Code:

// ...
BOOL CALLBACK ProcessTrayChildren (HWND hwnd, LPARAM lParam);
BOOL CALLBACK ProcessIcons (HWND hwnd, LPARAM lParam);
// ...
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    HWND hTray = ::FindWindow( "Shell_TrayWnd", NULL );
    if (hTray)
    {
        EnumChildWindows( hTray, (WNDENUMPROC)ProcessTrayChildren, 0 );
    }
}

BOOL CALLBACK ProcessTrayChildren( HWND hwnd, LPARAM lParam )
{
    char ClassName[256];
    GetClassName( hwnd, ClassName, sizeof( ClassName ) );

    if ( strcmp( ClassName, "TrayNotifyWnd" ) == 0 )
    {
        EnumChildWindows( hwnd, (WNDENUMPROC)ProcessIcons, 0 );
        return FALSE;
    }
    return TRUE;
}

BOOL CALLBACK ProcessIcons( HWND hwnd, LPARAM lParam )
{
    RECT rect_tb;
    int y,x;

    char ClassName[256];
    GetClassName( hwnd, ClassName, sizeof(ClassName) );

    if ( strcmp( ClassName, "ToolbarWindow32" ) == 0 )
    {
        ::GetClientRect( hwnd, &rect_tb );
        for ( y=rect_tb.left; y<=rect_tb.right; y++ )
        {
            for ( x=rect_tb.top; x<=rect_tb.bottom; x++ )
            {
                ::SendMessage( hwnd, WM_MOUSEMOVE, 0, MAKELONG(x,y) );
            }
        }
        return FALSE;
    }
    return TRUE;
}
// ...



[Ovu poruku je menjao X Files dana 16.11.2008. u 10:13 GMT+1]
[ mmix @ 16.11.2008. 09:31 ] @
Mislim da mozes i da skratis kod i izbacis enumeracije i iskoristis FindWindowEx api samo sa imenom klase (postoji samo jedan takav prozor ako se ne varam)

FindWindowEx(NULL, NULL, "TrayNotifyWnd", NULL);

i isto ako se ne varam mozes slobodono da se prosetas po ovom hWnd-u

Za ovaj hack postoje jos dva problema pored ovih koje si naveo. Prvo mrtve ikonice mogu da se nadju i u "skrivenom" delu system tray-a (znaci moras da prvo uradis expand tray-a ako hoces da ih sve istrebis) i drugo mora da ide mali delta za pomeraj misa da ne bi bilo preskocenih ikonica. Recimo da je delta 8 piksela, imas XxY ukupno cetiri 'udara' u jedno mesto za ikonicu, posto se ikonice sklanjaju odmah pri pomeranju misa i tray se shiftuje i sad ti je ispod misa druga ikonica koja se nece odmah skloniti jer ceka svoj pomeraj misa i moze lako biti preskocena.
[ X Files @ 16.11.2008. 10:08 ] @
^
Da, definitivno može i kraće, jednostavno sam kopirao već postojeći kod kao polazni.

To za mali pomeraj je svakako bitno (jer ako se ne varam, nemamo odmah povratni info o uklanjanju ikone, pa da ostanemo na istom pikselu dok ima šta da se ukloni), kao što je bitno i da se krene "odozgo na dole", jer se ikone slažu kao tetris, odnosno padaju dole.

Kada bih radio kod za sebe (a da budem siguran da radi besprekorno), možda bih uveo i par prolaza:
for ( int prolaz=0; prolaz<BROJ_PROLAZA; ++prolaz)
{
// ovde ceo kod
}
... jer očekujem da prolazi rade vrlo brzo.

Expand treba obavezno.
[ X Files @ 16.11.2008. 10:27 ] @
^
A mozda i povremenu rekalkulaciju granica poligona.
[ baseQ @ 16.11.2008. 10:56 ] @
Hvala ljudi,
to je to.
Koristim bcb :)
I da, koristim tray u vise redova :)

thx 1ce more
pozz svima
[ X Files @ 16.11.2008. 11:03 ] @
OT:
Baš sad gledam nešto u vezi tray-a u više linija (barem kod Viste).
2 reda Quick launch ikona = 3 reda tray ikona (al' su se zbile, svaka čast). Nisam to ranije uočavao.
[ deerbeer @ 16.11.2008. 11:16 ] @
http://www.themssforum.com/MFC/Refresh-system/

Mislim da nema mnogo potrebe za ovom gore egzibicijom "proccess Icons" itd ..
Dovoljno je staviti u OnDestroy handleru od prozora ikonice Shell_NotifyIcon(NIM_DELETE,&IconData);
i radice. Meni je tako radilo , bas sad isprobah pre neki minut cisto da budem siguran .
[ mmix @ 16.11.2008. 11:18 ] @
E sad kad smo sve to rekli, ja bih ti opet preporucio da ne radis sve ovo vec da lociras glavni HWND procesa koji gasis nasilno i umesto da upucas proces posalji mu WM_CLOSE i pusti ga koji trenutak da se ugasi sam i verovatno ce ikonica sama nestati kao deo cleanup-a aplikacije koju gasis pa ti nista od ovoga ne treba. Ikonica nije jedini problem koji mozes da imas sa nasilnim ubijanjem procesa (samo je problem koji vidis), ima tu i drugih vaznijih problema (ako ubijes proces tokom asinhronog upisivanja u fajl i slicno).

[ mmix @ 16.11.2008. 12:02 ] @
Citat:
deerbeer: Dovoljno je staviti u OnDestroy handleru od prozora ikonice Shell_NotifyIcon(NIM_DELETE,&IconData);
i radice. Meni je tako radilo , bas sad isprobah pre neki minut cisto da budem siguran .


Jos samo treba da pogodis koji hWnd i IconID koristi aplikacija koju je upravo ubio.
[ X Files @ 16.11.2008. 15:20 ] @
Citat:

@deerbeer
Dovoljno je staviti u OnDestroy handleru od prozora ikonice Shell_NotifyIcon(NIM_DELETE,&IconData);

Nikola, da li govorimo o istom?
Problem je u tome sto kada se nasilno (TerminateProcess/Task manager>End Process) ubije aplikacija koja koristi tray, ona ne stigne da izvrsi clean-up kod u koji spada i Shell_NotifyIcon(NIM_DELETE,&IconData).

Citat:

@mmix
E sad kad smo sve to rekli, ja bih ti opet preporucio da ne radis sve ovo vec da lociras glavni HWND procesa koji gasis nasilno i umesto da upucas proces posalji mu WM_CLOSE i pusti ga koji trenutak da se ugasi sam i verovatno ce ikonica sama nestati kao deo cleanup-a aplikacije koju gasis pa ti nista od ovoga ne treba.

Naravno. Slanje WM_CLOSE u message queue aplikacije je prvo sto bi trebalo pokusati.

@BaseQ
Jesi li pokusao ovo sa slanjem WM_CLOSE, to je svakako najbolje resenje ?
[ baseQ @ 16.11.2008. 15:47 ] @
Ne iskreno nisam,
ceo program mi se javio iz potrebe
sto neke procese ne mozes da ugasis
iz task managera, a nakon toga sam ga doradio
za gasenje nekih programa p2p koji
dl-uju raznorazne stvari :) i jos ubacio
i za gasenje sistema itd.
Mislim nastao je za ubijanje procesa
i....... eto... bezveze.
Neznam, probacu sigurno.
Za sad sve radi kao sto sam i zamislio,
iz ciste moje potrebe :)
Elem i pod XP-om, kada je dvoredni
u tray-u su tri reda ikonica.
Ovo Windows 2003 je u stvari XP x64 bitni ili ti zvanicno Windows Server 2003

poz
[ deerbeer @ 16.11.2008. 17:43 ] @
Citat:
X Files: Naravno. Slanje WM_CLOSE u message queue aplikacije je prvo sto bi trebalo pokusati.
Nikola, da li govorimo o istom?
Problem je u tome sto kada se nasilno (TerminateProcess/Task manager>End Process) ubije aplikacija koja koristi tray, ona ne stigne da izvrsi clean-up kod u koji spada i Shell_NotifyIcon(NIM_DELETE,&IconData).
@BaseQ
Jesi li pokusao ovo sa slanjem WM_CLOSE, to je svakako najbolje resenje ?

Nisam mozda procitao na pocetku dobro ,al sad vidim o cemu se radi .
Nikad ne bi trebalo gasiti ni app ni thread sa TerminateProces ili TerminateThread .
To su funkcije koje su na raspolaganju kao "zadnje sredstvo"

WM_CLOSE poruka ce posredno da posalje i poruku WM_DESTROY (ili OnDestroy hanlder f-ja u MFC-u)
koja unistava prozor ikonice samim tim i brise i slicicu ikonice.E sad bi bilo najbolje da hvata tu poruku WM_DESTROY i da u njoj uradi
Shell_NotifyIcon(NIM_DELETE,&IconData). Znaci regularno gasenje app bez ikakvog
nasilnog gasenja procesa . to je ono sto je i mmix rekao .
[ baseQ @ 16.11.2008. 18:47 ] @
Ne bih da zvucim tvrdoglavo, ili da budem pogresno shvacen.
Ali aplikacija je ares p2p program, i ima nesto vrlo neobicno sa njom
u nekim slucajevima, da kazem 50/50 'odsto a to je da
cak i kad se regularno ugasi, ume da ostane proces u pozadini
iako je 'kao' ugasen pa cak i ikonica is stray nestala.
Naravno to je bug, koji se javlja u pola slucajeva iako je sam program pretrpeo
dosta novih verzija, problem se taj javlja konstantno, u bilo kojoj verziji win xp-a
staroj ili novo instaliranoj.
Naravno, Vi svi ste apsoluno u pravu,
resenje jeste ok i by the book, kao sto i treba
ali hocu da kazem da se na ovom windows-u punom nekih crnih rupa
i tamne materije, sa vremena na vreme javljaju potrebe za
hack resenjima i verzijama koda kao sto je ovaj slucaj sa mnom.

Elem i jednu verziju i drugu ste mi Vi uradili
tako da hvala svima.

toj bi bilo to.

stay sharp guys :)