Einzelnen Beitrag anzeigen

emteg

Registriert seit: 16. Jun 2005
71 Beiträge
 
Delphi 2009 Architect
 
#2

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

  Alt 4. Aug 2006, 11:40
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?
  Mit Zitat antworten Zitat