Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Taskbareintrag nur für fenster, nicht für die Anwendung (https://www.delphipraxis.net/74436-taskbareintrag-nur-fuer-fenster-nicht-fuer-die-anwendung.html)

emteg 3. Aug 2006 10:15


Taskbareintrag nur für fenster, nicht für die Anwendung
 
Mein Programm soll aus mehreren Fenstern bestehen, die man unabhänig von einander öffnen, schließen, maximieren und minimieren können soll. Dazu möchte ich es gerne erreichen, dass es kein sog. "Hauptfenster" gibt, das die ganze anwendung minimiert oder schließt, wenn man den entsprechenden button drückt, sondern eben nur sich selbst.

Ungefähr so wie beim Firefox: das Downloadfenster scheint da vollkommen unabhänig zu sein, man kann mit den browser fenstern machen was man will, das programm wird erst beendet, wenn das letzte fenster geschlossen wird. Genau so frei möchte ich meine fenster auch haben - wie haben die jungs von mozilla das gemacht?

Also, ich bin mir sicher, dass das unter d2006 w32 auch möglich ist - nur wie?

emteg 4. Aug 2006 11:40

Re: Taskbareintrag nur für fenster, nicht für die Anwendung
 
Warum bekommt man hier eigentlich keine Antwort auf so ein Problem? Naja, immerhin hab ichs mit google und sehr viel ausprobieren jetzt selber hinbekommen. Und ich beschreibe jetzt mal wie das geht, falls noch andere Menschen etwas ähnliches machen möchten.

In meinem Testprojekt arbeite ich mit 2 Forms, das Form1 ist ganz normal das MainForm der Anwendung. Man kann seiner Anwendung beliebig viele forms verpassen, allerdings benötigt man eines, dass auf jeden fall beim start erzeugt wird. Alle anderen kann man beliebig zur Laufzeit erzeugen/zerstören.

Das Form1 sollte ein TrayIcon bereitstellen und eventuell mittel und Wege, mit denen Man die forms, die es gibt, in einer liste speichern kann. Ok, genug der Vorrede, jetzt mal ein bischen code:

Im Form1 muss im Designer Visible auf false gesetzt werden. Dannach erstellen wir uns ein zweites Form, stellen Visible auf true, speichern und schauen mal in die Projektdatei.
Delphi-Quellcode:
  Application.Initialize;
  Application.ShowMainForm:=false;      //Diese Zeile muss eingefügt werden.
  Application.CreateForm(TForm1, Form1);
  Application.CreateForm(TForm2, Form2);
  Application.Run;
Was ist hier passiert:
Das Form, das zu erst erzeugt wird, ist das MainForm der Anwendung. Wenn das MainForm geschlossen wird, wird das Programm beendet. Wenn das MainForm minimiert wird, werden alle Fenster des Programms minimiert.
Wenn man das Programm jetzt mal ausführt erscheint nur das Form2 und im Taskbar ein Button mit dem Namen des Projekts. Das wird jetzt ein wenig aufgepeppt.

Das Form2 braucht eine zusätzliche Prozedur:
Delphi-Quellcode:
TForm2 = class(TForm)
    procedure CreateParams(var Params: TCreateParams); override;
  private
    { Private declarations }
  public
    { Public declarations }
  end;
{...}
procedure TForm2.CreateParams(var Params: TCreateParams);
begin
  inherited;                           //Dies bei allen Forms des Programms
  Params.ExStyle:=WS_EX_APPWINDOW;     //
  Params.WndParent := GetDesktopwindow; //

  { Das muss nur genau ein mal im ganzen Programm ausgeführt werden }
  SetWindowLong( Application.Handle, GWL_EXSTYLE,                
                GetWindowLong(Application.Handle, GWL_EXSTYLE) or
                WS_EX_TOOLWINDOW and not WS_EX_APPWINDOW);
end;
Jedes Form der Anwendung, dass einen Eigenen Taskbareintrag haben soll, muss diese Prozedur haben. Das Params.ExStyle sorgt dafür, dass das Form einen eigenen Taskbareintrag erhält. Params.WndParent sorgt dafür, dass das Fenster zum Desktop und nicht zur Application gehört. Es würde jetzt nicht mehr minimert werden, wenn man das Form1 minimiert.
Die Prozedur SetWindowLong() muss im ganzen Programm ein mal ausgeführt werden. In diesem Beispiel wird Form2 immer beim start erstellt, es kann also in die CreateParams Prozedur von Form2 hinzugefügt werden. Diese Prozedur sorgt dafür, dass die Anwendung selber keinen Taskbar eintrag mehr hat.

Das wars auch schon. Jetzt hat man ein Programm, bei dem rein äußerlich alle Fenster die gleichen Rechte haben. Man muss sich auf jeden fall noch überlegen, wie man dafür sorgen kann, dass man das Programm auch dann noch beenden kann, wenn der Benutzer alle sichtbaren fenster schließt. Eine möglichkeit wäre ein TrayIcon, das vom Form1 erstellt wird.

Vorschläge, Kritik, Fragen?

Guido Eisenbeis 21. Mär 2007 01:42

Re: Taskbareintrag nur für fenster, nicht für die Anwendung
 
Hallo emteg.

Zitat:

Zitat von emteg
Warum bekommt man hier eigentlich keine Antwort auf so ein Problem?

Tja, das habe ich mich bei verschiedenen (eigenen) Problemen auch schon gefragt. :gruebel:

Ok, dieser Thread ist ja nun nicht mehr der neueste. Aber weil das Problem auch bei mir schon mal ein Thema war, hier ein Lob: Deinen Tip/Code habe ich ausprobiert. Er ist innovativ und funktioniert einwandfrei! Und du hast dir die Mühe gemacht, ihn zu beschreiben und mit uns anderen DPlern zu teilen! :thumb:

Mein Problem vor ein paar Monaten war sehr ähnlich, ich wollte jedoch auch noch die Mainform (unabhängig) mitbenutzen und ein Subform musste topmost gesetzt werden. Das war noch ein Zacken schwierieger! Hätte ich deine Lösung damals gefungen, hätte ich das Ganze vielleicht anders gelöst. Nämlich so wie dein Tip es vorschlägt.

Viele Grüße,
Guido.


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:25 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz