Entwickler-Ecke

Sonstiges (Delphi) - Taskbar zeigt Anwendung auch nach Schließen


Gerhard_S - Mo 30.09.13 19:42
Titel: Taskbar zeigt Anwendung auch nach Schließen
Hallo,
unter Windows 7 wird meine aktuelle Anwendung (Delphi XE 2) auch nach dem Schließen noch in der Taskbar gezeigt - bis ich auf das Icon in der Taskbar klicke. Ist das so gewollt oder habe ich vergessen, eines oder mehrere zur Laufzeit erzeugte Elemente wieder freizugeben? Bei anderen Anwendungen ist das nicht so.
In diesem Zusammenhang die Frage: wenn ich per Button eine modal erzeugte Form auf ModalResult := mrOK setze, werden dann auch die dynamisch erzeugten Steuerungselemente (Buttons etc.) auf der Form freigegeben?


WasWeißDennIch - Mo 30.09.13 19:51

Zur Taskbar kann ich nichts sagen, aber wieso sollten die erzeugten Elemente freigegeben werden, sobald das ModalResult zugewiesen wird? Das geschieht erst, wenn man das selber macht oder der angegebene Owner (sofern vorhanden) freigegeben wird.


Mathematiker - Mo 30.09.13 20:06

Hallo,
user profile iconGerhard_S hat folgendes geschrieben Zum zitierten Posting springen:
Hallo,
unter Windows 7 wird meine aktuelle Anwendung (Delphi XE 2) auch nach dem Schließen noch in der Taskbar gezeigt - bis ich auf das Icon in der Taskbar klicke.

diesen Effekt kenne ich von älteren Windows, allerdings nur bei einigen Programmen. Die Ursache habe ich nicht gefunden, bekam aber den Tip, vor dem Schließen des Programms das Formular zu verstecken.
Alternativ sollte auch gehen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
uses ShellApi;
...
Procedure TaskBarRemoveIcon;
var tnid: TNOTIFYICONDATA;
begin
  tnid.cbSize := sizeof(TNOTIFYICONDATA);
  tnid.Wnd := Form1.Handle;
  tnid.uID := 1;
  Shell_NotifyIcon(NIM_DELETE, @tnid);
end;

Ob es unter Win 7 funktioniert, kann ich aber nicht einschätzen.

Beste Grüße
Mathematiker


jaenicke - Mo 30.09.13 20:48

Das funktioniert schon, setzt aber voraus, dass man das Tray Icon manuell über die API anzeigt. Das dürfte allerdings eher die Ausnahme sein.

Sinnvoller ist natürlich direkt die Komponente TTrayIcon zu benutzen und die räumt normalerweise sauber auf. Vor dem Schließen des Formulars kann man auch einfach in OnClose noch einmal explizit Visible auf False setzen.

Meistens rühren solche Probleme aber eher von Aufrufen von Application.Terminate oder Halt oder ähnlichen Schweinereien her. ;-)
Da dabei die Anwendung nicht sauber beendet wird, bleiben insbesondere bei Halt oft solche Reste übrig.

Aber um genaueres zu sagen brauchen wir erst einmal mehr Informationen. Wie zeigst du das Tray Icon an? Wie beendest du die Anwendung?


Gerhard_S - Mo 30.09.13 21:55

Das TrayIcon zeige "ich" gar nicht an, das macht Delphi für mich - ohne eine Zeile Code. Anzeige und Löschen des Icons im linken Teil der Taskbar zur Laufzeit sind das werksseitig voreingestellte Verhalten.
Ich habe gerade gemerkt, dass beim Anwendungsstart zwei nicht ganz übereinander liegende Icons erzeugt werden. Das hat mit dem Splashscreen ("verfügbares Formular" in der Projektverwaltung) zu tun. Wenn ich auf ihn verzichte, wird die Anwendung vollständig geschlossen - und das Icon in der Taskbar verschwindet sofort. So ganz verstehe ich das nicht. In der dpr-Datei steht:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
SplashScreen := TSplashScreen.Create(Application);
SplashScreen.Show;
SplashScreen.Refresh;
Application.Initialize;
Sleep(2000);
Application.MainFormOnTaskbar := True;
SplashScreen.Free; 
Application.CreateForm(TForm1, Form1);
//usw. usf.


Mathematiker - Mo 30.09.13 22:39

Hallo,
user profile iconGerhard_S hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
2:
3:
SplashScreen := TSplashScreen.Create(Application);
SplashScreen.Show;
SplashScreen.Refresh; ...

Ich habe dieses Refresh schon in Beispielen gesehen, aber auch

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
  SplashScreen := TSplashScreen.Create(Application);
   try
     SplashScreen.Show;
     Application.Initialize;
     SplashScreen.Update;     // mit Update 
     Sleep(1000);
     Application.CreateForm(TForm1, Form1);
     SplashScreen.Hide;       // und vor dem Löschen erst Verstecken
   finally
     SplashScreen.Free;
   end;
     Application.Run;

Vielleicht hilft das. :nixweiss:

Beste Grüße
Mathematiker


Gerhard_S - Mo 30.09.13 23:29

Leider hilft's nicht. Das hier

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
begin
     ReportMemoryLeaksOnShutdown := True;
     SplashScreen := TSplashScreen.Create(Application);
     try
       SplashScreen.Show;
       Application.Initialize;
       SplashScreen.Update;
       Sleep(2000);
       Application.MainFormOnTaskbar := True;
       SplashScreen.Free;
       Application.CreateForm(TForm1, Form1);
       Application.Title := 'wtsupport';
       Application.CreateForm(TForm4, Form4);
       Application.CreateForm(TForm11, Form11);
       Application.CreateForm(TForm13, Form13);
       Application.CreateForm(TForm15, Form15);
       SplashScreen.Hide;
     finally
       SplashScreen.Free;
     end;
     Application.Run;
end.

zeigt kurz das Icon in der Taskbar an und löscht es wieder. Das geht so schnell, dass ich von der Anwendung nichts sehe.
Unter der Kontrolle des Debuggers erscheint ein leeres Fenster und danach eine Meldung, die ich noch nie gesehen habe:
>>Im Projekt wtsupport.exe sind zu viel auseinander folgende Exceptions aufgetreten: "access violation at 0x00000000: read of address 0x00000000. Prozess wurde angehalten. Mit Einzelne Anweisung oder Start fortsetzen.<<
Deshalb bin ich wieder zum "guten alten" Code zurückgekehrt:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
     ReportMemoryLeaksOnShutdown := True; 
     SplashScreen := TSplashScreen.Create(Application);
     SplashScreen.Show;
     SplashScreen.Refresh;
     Application.Initialize;
     Sleep(2000);
     Application.MainFormOnTaskbar := True;
     SplashScreen.Free;
     Application.CreateForm(TForm1, Form1);
     Application.Title := 'wtsupport';
     Application.CreateForm(TForm4, Form4);
     Application.CreateForm(TForm11, Form11);
     Application.CreateForm(TForm13, Form13);
     Application.CreateForm(TForm15, Form15);
     Application.Run;

Das Problem mit den 2 Icons in der Taskbar konnte ich lokalisieren (es ging um den Aufbau einer SFTP-Verbindung, die nicht wieder abgebaut wurde).


jaenicke - Mo 30.09.13 23:50

user profile iconGerhard_S hat folgendes geschrieben Zum zitierten Posting springen:
Unter der Kontrolle des Debuggers erscheint ein leeres Fenster und danach eine Meldung, die ich noch nie gesehen habe:
>>Im Projekt wtsupport.exe sind zu viel auseinander folgende Exceptions aufgetreten: "access violation at 0x00000000: read of address 0x00000000. Prozess wurde angehalten. Mit Einzelne Anweisung oder Start fortsetzen.<<
Weil du den Splashscreen einmal zu viel freigibst:
user profile iconGerhard_S hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
begin
     ReportMemoryLeaksOnShutdown := True;
     SplashScreen := TSplashScreen.Create(Application);
     try
       SplashScreen.Show;
       Application.Initialize;
       SplashScreen.Update;
       Sleep(2000);
       Application.MainFormOnTaskbar := True;
       SplashScreen.Free;
       Application.CreateForm(TForm1, Form1);
       Application.Title := 'wtsupport';
       Application.CreateForm(TForm4, Form4);
       Application.CreateForm(TForm11, Form11);
       Application.CreateForm(TForm13, Form13);
       Application.CreateForm(TForm15, Form15);
       SplashScreen.Hide;
     finally
       SplashScreen.Free;
     end;
     Application.Run;
end.
Die Freigabe im Finally gibt dann den Fehler, da das Fenster da ja schon nicht mehr existiert...


Gerhard_S - Di 01.10.13 02:19

Oh, das hatte ich übersehen.
Danke.


Christian213 - Mi 16.10.13 13:10

Wenn's immer noch nicht klappt, so könnte man noch direkt Shell_NotifyIcon aus der Win32-API aufrufen: http://msdn.microsoft.com/en-us/library/windows/desktop/bb762159%28v=vs.85%29.aspx

Edit: Falscher Link