Entwickler-Ecke

Off Topic - [Win 7x64]Tray-Leiste aktualisieren


Hidden - Do 09.09.10 13:14
Titel: [Win 7x64]Tray-Leiste aktualisieren
Moin!

Ich habe bei verschiedenen Anwendungen(nicht meine) beobachtet, dass das Tray-Icon nach dem Beenden weiter angezeigt wird. Ein Prozess existiert nicht mehr, und ein Mouse-Over über das Icon bringt es zum verschwinden.

Also nehme ich mal an, dass Windows beim Mouse-Over bemerkt, dass das Tray-Icon gar nicht mehr existiert.

Gibt es eine Möglichkeit, Windows dazu aufzufordern, die Tray-Symbole neu zu überprüfen?
Konkret möchte ich eine Anwendung per TerminateProcess beenden und neu starten, aber jedes Mal kommen zwei Tray-Icons hinzu, bis ich sie mit der Maus berühre.

lg,


elundril - Do 09.09.10 13:18

Könntest du nicht n WM_Paint an das Handle vom Tray schicken? Mit X-Spy sollte man das eigentlich leicht finden können.

lg elundril


Hidden - Do 09.09.10 14:51

Das wird wohl, wie ich gerade merke, nicht ausreichen: Das Mouse-Over muss wirklich über dem konkreten Tray-Icon stattfinden, nicht über der Leiste.
Werde gleich mal versuchen, alle Tray-Icons zu listen, und jedes einmal irgendwie anzusprechen.

lg,


spawn89 - Di 28.09.10 15:58

[bump]
Das Problem müsste doch jeder schonmal gehabt haben. Und keiner hat eine Lösung? :eyes:


Hidden - Di 28.09.10 17:11

Meine "Lösung" besteht im Moment für den Eigenbedarf darin, dass ich mit der Maus(zur Zeit manuell) einmal über die Trayleiste fahre :nixweiss:
Ich hatte leider nicht die Zeit, da weiter zu experimentieren :|

lg,


Delete - Di 28.09.10 17:36

Wenn man Programme richtig beendet, dann passiert das auch nicht. Aber wenn man ein Programm abschießt, dann kann der Code zum Entfernen des Icons nicht aufgerufen werden.


Hidden - Di 28.09.10 17:40

Moin!

Da das Programm zumindest in meinem Fall zuerst einen Dialog ausgefüllt haben will, bevor es sich beenden lässt, ist normales Schließen leider keine Option :(
Eben darum, die invaliden Tray-Icons danach manuell zu entfernen, soll es gehen. Z.B. für einen eigenen Taskmanager.

lg,


Regan - Di 28.09.10 21:04

Dann deistalliere dieses Programm einfach. Programme, die sich nicht schließen lassen, müssen weg.


elundril - Di 28.09.10 21:58

user profile iconRegan hat folgendes geschrieben Zum zitierten Posting springen:
Dann deistalliere dieses Programm einfach. Programme, die sich nicht schließen lassen, müssen weg.


Windows entfernen? :mrgreen:


Regan - Di 28.09.10 22:05

user profile iconelundril hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconRegan hat folgendes geschrieben Zum zitierten Posting springen:
Dann deistalliere dieses Programm einfach. Programme, die sich nicht schließen lassen, müssen weg.


Windows entfernen? :mrgreen:

Wird sowieso überbewertet ;)


spawn89 - Di 28.09.10 22:07

user profile iconRegan hat folgendes geschrieben Zum zitierten Posting springen:
Dann deistalliere dieses Programm einfach. Programme, die sich nicht schließen lassen, müssen weg.


Ich hab etliche Fälle, bei denen das 'auf normalem Weg' passiert.
Beispielsweise TrueCrypt beim Mounten / Dismounten per commandline.
Oder LCDMon (G15-Treiber). Oder oder oder...
Da gibt es keine Alternativen.

Wenn keiner eine Lösung hat, werd ich wohl auch mit der Maus durch die gegend kurven müssen... :roll:


Gerd Kayser - Mi 29.09.10 01:14

user profile iconHidden hat folgendes geschrieben Zum zitierten Posting springen:
Gibt es eine Möglichkeit, Windows dazu aufzufordern, die Tray-Symbole neu zu überprüfen?
Werf mal einen Blick darauf: http://malwareanalysis.com/CommunityServer/blogs/geffner/archive/2008/02/15/985.aspx

Vielleicht hilft Dir das weiter.


Dezipaitor - Mi 29.09.10 13:36

Versuch mal:

C#-Quelltext
1:
2:
3:
4:
#define TM_REFRESH  (WM_USER + 0x161)
hwnd = FindWindowEx(NULL, NULL, _T("Shell_TrayWnd"), NULL);
if (hwnd)
  PostMessage(hwnd, TM_REFRESH, 00);


spawn89 - Mi 29.09.10 15:08

Nope, geht nicht. Wär ja auch zu schön.

Hier endlich die Delphi-Workaround-Lösung:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
procedure TForm1.RefreshTraybar;
var
  ClRct: TRect; 
  hTray: THandle;
  hNotfyArea: THandle;
  x: Integer;
  y: Integer;
begin
  hTray := FindWindow('Shell_TrayWnd','');
  if hTray = 0 then
    Exit;
         
  hNotfyArea := FindWindowEx(hTray, 0'TrayNotifyWnd'nil);
  hNotfyArea := FindWindowEx(hNotfyArea, 0'SysPager'nil);
  hNotfyArea := FindWindowEx(hNotfyArea, 0'ToolbarWindow32'nil);
  if hNotfyArea = 0 then
    Exit;

  Windows.GetClientRect(hNotfyArea, ClRct);
  x := 0;
  y := 0;
  while x < ClRct.Right - ClRct.Left do
  begin
    while y < ClRct.Bottom - ClRct.Top do
    begin
      SendMessage(hNotfyArea, WM_MOUSEMOVE, 0, (y shl 16) + x);
      inc(y, 5);
    end;
    inc(x, 5);
  end;
end;


Edit:
Und jetzt find ich gerade den [http://www.delphipraxis.net/144257-tray-icon-entfernen-nach-beenden-des-prozesses.html] Thread... Da wird nochmal auf die Icon-Größe eingegangen. Aber es ist auch nur ein unschöner Workaround.


Dezipaitor - Mi 29.09.10 19:19

Geht das überhaupt in Windows 7? Weil da ist ja ein extra Kasten mit den Icons drin, wenn man auf den Pfeil klickt.


spawn89 - Mi 29.09.10 19:46

Hmm ich habs auf XP gecodet, getestet und es funktionierte.
Jetzt hab ich die exe hier auf Win 7 64 bit und es geht gar nicht. Ich glaub Sendmessage schlägt fehl (32 <-> 64?). WinSpy sagt das die Fensterstruktur die gleiche ist.


Gerd Kayser - Mi 29.09.10 21:33

user profile iconspawn89 hat folgendes geschrieben Zum zitierten Posting springen:
WinSpy sagt das die Fensterstruktur die gleiche ist.
Ich kann es zwar nicht überprüfen, weil ich nur Windows 7 mit 32 Bit habe, aber 'ToolbarWindow32' springt mir da förmlich ins Auge. Das würde ich zuerst überprüfen.


Marc. - Mi 29.09.10 22:14

user profile iconspawn89 hat folgendes geschrieben Zum zitierten Posting springen:
Nope, geht nicht. Wär ja auch zu schön.

Hier endlich die Delphi-Workaround-Lösung:

Du musst allerdings bedenken, dass die "TrayIconBox" ein anderes Handle hat:

Delphi-Quelltext
1:
2:
  hNotfyArea := FindWindow('NotifyIconOverflowWindow''');
  hNotfyArea := FindWindowEx(hNotfyArea, 0'ToolbarWindow32'nil);

So lässt sich auf jeden Fall die Box unter Windows7 64Bit updaten. :zwinker:
(Es ist idT. die ToolbarWindow32 und nicht 64!)


Darüberhinaus frage ich mich, wie Du die Koordinaten als Paramter bestimmst:
MSDN hat folgendes geschrieben:
lParam
The low-order word specifies the x-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.
The high-order word specifies the y-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.

Da kann IMHO etwas nicht stimmen.

Letztendlich passen die mittels GetClientRect bestimmten Größen nicht mit denen überein, die mir WinSpy angibt. :gruebel: