Mehrere geöffnete Formulare

Für Fragen von Einsteigern und Programmieranfängern...
Bernie110
Beiträge: 120
Registriert: Mo 10. Feb 2020, 17:43

Mehrere geöffnete Formulare

Beitrag von Bernie110 »

Hallo Zusammen,

in meinem Programm kann man gleichzeitig mehrere Formulare geöffnet haben.
Jetzt würde ich mir gerne irgendwo eine Übersicht im Hauptformular schaffen,
welche anzeigt, welche Formulare gerade geöffnet sind.
Also so eine Art Liste aller derzeit geöffneten Forumlaren.
Über diese Liste möchte ich auch zum jeweiligen Formular navigieren, bzw dieses per Klick angezeigt bekommen. Sprich in den Vordergund bringen.
Auch sollte es möglich sein Formulare über diese Liste zu schliessen.
Die Formulare zeigen nur Übersichtsdaten an.
Info zu den Formularen :
Alle haben als PopupParent das Hauptmenu-Form.
Alle Forms werden erstellt und bei Close wieder zerstört.

Keine Ahnung .
Wie macht ihr so etwas ?
Jemand nen Tip ?

Danke für eure Antworten
Lg Bernie

NoCee
Beiträge: 170
Registriert: Do 3. Mär 2011, 21:34
OS, Lazarus, FPC: WinXp/7/10 Opensuse13.2/Leap15.3 (L 2.2.0 FPC 3.2.2 )
CPU-Target: Intel 32/64Bit, ARM9
Wohnort: Ulm

Re: Mehrere geöffnete Formulare

Beitrag von NoCee »

Hallo,

PageControl keine Option?
Alles Seiten da, Navigation easy.

Gruß
NoCee

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1430
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Mehrere geöffnete Formulare

Beitrag von fliegermichl »

Ich denke Screen.Forms ist dein Freund

Bernie110
Beiträge: 120
Registriert: Mo 10. Feb 2020, 17:43

Re: Mehrere geöffnete Formulare

Beitrag von Bernie110 »

@NoCee Ich wollte eigentlich ein PageControl vermeiden. Liegt aber hauptsächlich daran, dass ich bisher keine Möglichkeit gefunden habe den Hintergrund durchsichtig zumachen.

@FliegerMichel

Danke für den Hinweis.
Habe einen Code gefunden der damit was macht

Code: Alles auswählen

procedure TForm1.CreateFormFromName(const FormName: String; EmbbPanel: TPanel);
var
  f,v : TForm ;
begin
  v := FindForm( FormName );
  if Assigned(v) then
  begin
    v.show;
    Exit;
  end;
  f := TForm.Create( EmbbPanel );
  f.Hint := FormName ;
  f.Parent := EmbbPanel ;
  f.BorderStyle := bsNone;
  f.BorderIcons := [];
  f.Align := alClient;
  f.Visible := true;
end;   

function TForm1.FindForm( const FormName : String ): TForm;
var
   i : Integer;
begin
  Result := nil;
  for i := 0 to Screen.FormCount - 1 do
  begin
    if Screen.Forms[ i ].Hint = FormName then
    begin
      Result := Screen.Forms[ i ] ;
    end;
  end;
end; 


Soweit verstanden. Und damit könnte man eine Liste befüllen.
Wie bringt man dann aus dieser Liste ein Formular in den Vordergund bzw schliesst man es ...
Sorry wenn ich doofe Fragen stelle.. Aber mir fällt dazu nicht viel ein wie ich das gestallten könnte.
Hirnblockade :mrgreen:

Ich würde es vielleicht so machen.... Liste befüllen... per doppelklick das Form in den Vordergund bringen. Daneben einen Schalter
der die markierte Zeile ausliest und das Form dann per klick schliesst ? :wink:

Lg bernie

charlytango
Beiträge: 843
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Re: Mehrere geöffnete Formulare

Beitrag von charlytango »

NoCee hat geschrieben:
Mi 17. Feb 2021, 09:01
PageControl keine Option?
Alles Seiten da, Navigation easy.
klappt imho bei kleineren Projekten mit wenigen potentiellen Tabs auf dem PageControl recht gut. (Wenn damit gemeint ist die Formulare direkt ins Pagecontrol zu zeichnen). Wenn es um Formulare sagen wir mal >10 geht ist imho da schnell Schicht im Schacht.
Ein Sachbearbeiter vergleicht gerade zwei komplette Kundenstammdatensätze samt deren Bestellungen (= ein Kundensuchfenster, zwei Kundenstammfenster, vielleicht nochmal vier Bestellungsdetails und zwei Statistikfenster um den Rabatt zu validieren). Und dann dazwischen ein Anruf bei dem ihm die Rufnummernerkennung gleich nochmal so ein Set automatisch öffnet damit er dem Kunden detailliert Auskunft geben kann.
Da braucht der Sachbearbeiter eine Oberfläche in der er sich schnell zurecht findet und der Programmierer etwas bei dem er sich nicht die Finger bricht.

TScreen.Forms würde mich in diesem Zusammenhang auch nicht wirklich glücklich machen, denn die Klasse behandelt alle "Formulare" auf allen Screens aller Monitore.

The virtual screen (desktop) can include multiple physical Monitors.
Screen objects are Cursors, Fonts and Forms. For Delphi compatibility also (invisible) DataModules are listed.
The currently active Form, Control and Cursor also are tracked.


Und sich da jedes mal auf neue durch diese Liste arbeiten zu müssen macht aus meiner Sicht wenig Sinn, denn Formulare müssen ohnedies erzeugt werden. Da kann man ja eine Liste mitführen.

In größeren Projekten leite ich Formulare von einem (einfachen) gemeinsamen Vorfahren ab der nur einige für alle Fenster gültigen Properties enthält. zB Fenstertyp(Suchfenster, kundendetails, dieverse Listen, reports etc), Primary key, etwaige Statusswitches etc.

Die erzeugten Fenster werden letztlich in einer TFPObjectList verwaltet.
Fensterlisten, letzte geöffnete Forms, Unterbindung von Mehrfachöffnung (zB Mehrfaches Öffnen des Detailfensters aus einer Kundenliste verzweigt dann gleich zum bereits existierenden Fenster) oder Datensynchronisierung (Änderungen in einem Fenster die Auswirkung auf andere bereits offene Fenster haben können werden aktualisiert) und vieles mehr sind da möglich.

Die einzelnen erzeugten Formulare werden in die Oberfläche integriert bzw docked. Wahlweise voll integriert (zB in Controls wie Panels, PageControle, Notebooks etc) oder frei fliegend bzw modal oder nicht modal.

TDINotebook aus dem OPM ist nicht absolut perfekt aber mehr als brauchbar für eine Tabbed GUI

charlytango
Beiträge: 843
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Re: Mehrere geöffnete Formulare

Beitrag von charlytango »

Bernie110 hat geschrieben:
Mi 17. Feb 2021, 10:33
@NoCee Ich wollte eigentlich ein PageControl vermeiden. Liegt aber hauptsächlich daran, dass ich bisher keine Möglichkeit gefunden habe den Hintergrund durchsichtig zumachen.
Wieso willst du den Hintergrund eines Pagecontrols durchsichtig machen?
Bei einem eingedockten Fenster sieht man ja ohnedies nur die Farbe des Fensterhintergrundes?
Bitte erklären?


Hier geht es auch um grundsätzliches Design.

angenommen du hast ein Kundenformular frmKunde.

benutzt du in deiner Oberfläche immer das gleiche Formular für den nächsten Kunden (also ändern sich nur die Daten im Formular) oder erzeigst du für jeden Kunden ein eigenes Formular (sodass zwei Formulare mit unterschiedlichen Daten am Schirm zu sehen sein könnten ?)

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Mehrere geöffnete Formulare

Beitrag von Winni »

Hi!

1. Alle Forms müssen mit show (Nicht: showModal) angezeigt werden.
2. Wieso beim Schließen die Form zerstören? Wenn es nicht das Haptformular ist macht Lazarus automatisch beim FormXX.visible := false ein hide. Bei der nächsten Anzeige wird man durch Geschwindigkeit belohnt.
3. Buch führen bei mehreren Formularen muss nicht hilfreich sein, wenn die sich gegenseitig verdecken. Das ist aber nicht schlimm:
Wenn ein Formular mit show angezeigt werden, so passiert kann Folgendes passieren
a) Wenn es noch nicht angezeigt wird, wird es nun als oberste Form angezeigt
b) Falles es angezeigt wird, aber unter anderen Forms "vergraben" ist, kommt es in den Vordergrund.

Die Buch führen über den Status der Forms ist in sofoern nicht sinnvoll, weil das UI anzeigt: "FormXX" sichtbar, das hiilft Dir abr nix, wenn es uunten im Stapel liegt.

Winni

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Mehrere geöffnete Formulare

Beitrag von Winni »

Winni hat geschrieben:
Mi 17. Feb 2021, 11:08
Hi!

1. Alle Forms müssen mit show (Nicht: showModal) angezeigt werden.
2. Wieso beim Schließen die Form zerstören? Wenn es nicht das Haptformular ist macht Lazarus automatisch beim FormXX.visible := false ein hide. Bei der nächsten Anzeige wird man durch Geschwindigkeit belohnt.
3. Buch führen bei mehreren Formularen muss nicht hilfreich sein, wenn die sich gegenseitig verdecken. Das ist aber nicht schlimm:
Wenn ein Formular mit show angezeigt werden, so passiert kann Folgendes passieren
a) Wenn es noch nicht angezeigt wird, wird es nun als oberste Form angezeigt
b) Falles es angezeigt wird, aber unter anderen Forms "vergraben" ist, kommt es in den Vordergrund.

Die Buch führen über den Status der Forms ist in sofoern nicht sinnvoll, weil das UI anzeigt: "FormXX" sichtbar, das hilft Dir aber nix, wenn es unten im Stapel liegt.

Winni

charlytango
Beiträge: 843
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Re: Mehrere geöffnete Formulare

Beitrag von charlytango »

Nur mal so als Skizze

Code: Alles auswählen

procedure TWindowlist.OpenKunde(const rKunde: TPerson; const sCaption: string);
var
  myWnd:TfrmKunde;
  iTag:integer;
begin
  //eindeutigen des Fensters erzeugen Tag erzeugen
  //zB mit Fenstertyp und Primary Key des kunden
  iTag := strtoint( csWKUNDE + inttostr(rKunde.kdid));

  //Falls Fenster f diesen Tag existiert, Fenster anzeigen
  //andernfalls neu erzeugen
  if FindFormInPagesByTag(iTag,true) < 0 then
  begin
    myWnd := TfrmKunde.Create(Nil);

    if sCaption='' then
       myWnd.Caption:= rKunde.fullname
    else
      myWnd.Caption:= sCaption;

    myWnd.Tag:= iTag;
    myWnd.piKdID:=rKunde.kdid;  //Diverse IDs setzen
    myWnd.piID:=rKunde.kdid;    //die ID setzen 
    myWnd.piFormtype:=ciWKUNDE; //Typ des Fensters setzen
    myWnd.Initialize;  //Initialisiert das Fenster, schreibt Captions, befüllt das Fenster mit Daten
    Add(myWnd,3);  //hängt das gerade erzeugte Fenster in die Fensterliste ein
    Last; //geht zum letzten Eintrag der Fensterliste
  end;

end; 
Oft benötigte Fenstertypen werden quasi schon von der Fensterliste selbst erzeugt, spart Codezeilen, seltene Fenstertypen erzeuge ich im Code direkt

Bernie110
Beiträge: 120
Registriert: Mo 10. Feb 2020, 17:43

Re: Mehrere geöffnete Formulare

Beitrag von Bernie110 »

Hallo Zusammen,

ich seh schon, viele Wege führen nach Rom.
Danke für eure Antworten.

Ich will es trotzdem einmal mit einer Liste testen. ListView.
Diese Lösung wäre schon das was ich mir vorstellen würde.
Und schon gibts ein neues Problem.
Ich kann den Namen des geöffneten Formular darin speichern.
Jedoch wenn ich nun diesen String Namen verwenden möchte...
Zb so :

Code: Alles auswählen

var
   XForm_Name : String;

begin
   s:=ListView1.Items[ListView1.ItemIndex].SubItems[0];

   XForm_Name.FormStyle:=fsStayOnTop;
   XForm_Name.FormStyle:=fsNormal; 
...klappt es natürlich nicht.
Jetzt wäre die Frage wie man aus einem String ein TForm macht.. :?:

Lg Bernie

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1430
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Mehrere geöffnete Formulare

Beitrag von fliegermichl »

In einer TStringList kann man zusätzlich zu dem string auch Objekte (bzw. Pointer) speichern. Mit AddObject statt Add.

Code: Alles auswählen

procedure TForm1.Show(Sender : TObject);
var i : integer;
begin
 for i := 0 to Screen.Formcount - 1 do
  Listbox1.Items.AddObject(Screen.Forms[i].Name, Screen.Forms[i]);
end;
Um später darauf zuzugreifen kannst du die Eigenschaft Objects der TStringlist verwenden.

Bernie110
Beiträge: 120
Registriert: Mo 10. Feb 2020, 17:43

Re: Mehrere geöffnete Formulare

Beitrag von Bernie110 »

fliegermichl hat geschrieben:
Mi 17. Feb 2021, 14:06
In einer TStringList kann man zusätzlich zu dem string auch Objekte (bzw. Pointer) speichern. Mit AddObject statt Add.

Code: Alles auswählen

procedure TForm1.Show(Sender : TObject);
var i : integer;
begin
 for i := 0 to Screen.Formcount - 1 do
  Listbox1.Items.AddObject(Screen.Forms[i].Name, Screen.Forms[i]);
end;
Um später darauf zuzugreifen kannst du die Eigenschaft Objects der TStringlist verwenden.
Hi danke. Mist jetzt habe ich eine Listview verwendet und speichere den Formularnamen als String.
Kann man einen String nicht verwenden ?

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1430
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Mehrere geöffnete Formulare

Beitrag von fliegermichl »

Doch, geht auch. Mit Screen.FindForm

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Mehrere geöffnete Formulare

Beitrag von wp_xyz »

Bernie110 hat geschrieben:
Mi 17. Feb 2021, 14:42
Kann man einen String nicht verwenden ?
Und wenn zwei Formulare denselben Titel haben?

Bernie110
Beiträge: 120
Registriert: Mo 10. Feb 2020, 17:43

Re: Mehrere geöffnete Formulare

Beitrag von Bernie110 »

fliegermichl hat geschrieben:
Mi 17. Feb 2021, 14:57
Doch, geht auch. Mit Screen.FindForm
Perfekt !! Herzlichen Dank !
So gefällt es mir langsam ziemlich gut !!
Lg Benrie

Antworten