Autor Beitrag
colaka
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 200
Erhaltene Danke: 4

Win XP, W7
Delphi 2005 Prof.
BeitragVerfasst: Sa 18.06.11 16:51 
Hallo,

ich habe eine MDI-Anwendung, in der fast alle Fenster als MDI-Child definiert sind. Ein Fenster kann ich aber nicht als MDI-Child-Fenster einrichten, weil es größer als das Hauptfenster ist. Hier soll den Kunden eine Artikelauswahl angezeigt werden, und deshalb erstreckt sich dieses Fenster auch noch auf den 2. Monitor. Vom Hauptfenster rufe ich dieses Fenster mit dem folgenden Code auf:
ausblenden Delphi-Quelltext
1:
2:
  FArtikel2 := TFArtikel2.Create(self);
  FArtikel2.Show;

Das funktioniert auch, aber wenn das Fenster bereits geöffnet ist, soll es bei einem erneuten Aufruf nur in den Vordergrund geholt, anstatt immer wieder neu erzeugt zu werden. Und das ist mein Problem.

Zuerst dachte ich, ich kann das Fenster mit ShowModal anzeigen (das wäre mir eigentlich am liebsten), aber da kommt eine Zugriffsverletzung. Warum eigentlich? Dann habe ich versucht, abzufragen, ob das Fenster schon geöffnet ist ( if TFArtikel2.showing ), aber da kommt auch eine Zugriffsverletzung.

Im Forum habe ich seitenlange Anleitungen gefunden, wie man sämtliche geöffneten Fenster in irgendwelche Stringlisten eintragen und komplette Fensterverwaltungen erstellen kann, aber hier, wo der Name des in Frage kommenden Formulars bekannt ist, muß es doch eine einfache Abfrage geben, so in etwa: if Fenster.schongeöffnet then Fenster.bringtofront else erzeuge es.

Irgendwie habe ich da wohl einen Denkfehler.

Danke Ebi


Zuletzt bearbeitet von colaka am Sa 18.06.11 18:14, insgesamt 1-mal bearbeitet
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 18.06.11 17:35 
Füge es einfach als Popupfenster hinzu, dann kann es niemand hinter dein anderes Fenster bringen. ;-)
ausblenden Delphi-Quelltext
1:
Application.AddPopupForm(YourForm);					
Ansonsten kannst du es auch verstecken und dann mit ShowModal anzeigen.

Oder du setzt FormStyle auf fsStayOnTop oder du benutzt BringToFront oder ... :mrgreen:

Ach ja: ShowModal geht logischerweise nicht, weil das Fenster ja schon sichtbar ist. Da kannst du es ja nicht mehr sichtbar machen.
colaka Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 200
Erhaltene Danke: 4

Win XP, W7
Delphi 2005 Prof.
BeitragVerfasst: Mo 20.06.11 08:00 
Hallo,

ich habe die Frage jetzt wieder auf "offen" gesetzt, weil mein eigentliches Problem doch nicht richtig gelöst ist. Das einzige von Deinen Vorschlägen, das eine 2. Fensteröffnung verhindert, ist die Methode mit hide und showmodal. Das funktioniert auch, sieht aber unmöglich aus: Das Fenster poppt kurz auf, verschwindet dann wieder und wird dann erst richtig angezeigt. Bei fsStayOnTop und BringToFront kann man es vom Hauptfenster aus einfach nochmal erzeugen, und das war eigentlich das Problem, das ich verhindern will.

Es muß doch eine Möglichkeit geben, abzufragen, ob das Fenster schon geöffnet ist oder nicht. Und davon abhängig kann ich es dann entweder neu erzeugen oder in den Vordergrund bringen.

Danke Ebi
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6393
Erhaltene Danke: 147

Windows 7 + Windows 10
Sydney Prof + CE
BeitragVerfasst: Mo 20.06.11 08:57 
Meine Standard-Routine für diesen Fall:
ausblenden volle Höhe 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:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
Function Tfrm.MDIChildExist (frm : TForm) : Boolean;
var
  cnt : Word;
begin
  Result := False;
  if TForm(Owner).MDIChildCount > 0 then
  begin
    cnt := 0;
    while (cnt < TForm(Owner).MDIChildCount) and (not Result) do
    begin
      Result := (TForm(Owner).MDIChildren[cnt] = frm);
      if Result then
      begin
        try
          Result := (TForm(frm).Tag = 1);
        except
          Result := False;
        end;
        exit;
      end;
      inc (cnt);
    end;
  end// if
end;


procedure Tfrm.actAbwicklungJITExecute(Sender: TObject);
begin
  Screen.Cursor := crHourglass;
  try
    if MDIChildExist (frmJIT) then
  begin
      frmJIT.BringToFront;
  end
  else
  begin
    frmJIT := TfrmJIT.Create(Self);
  end;
  finally
    Screen.Cursor := crDefault;
  end;
end;


Erläuterung:
MDIChildExist läuft alle Fenster der MDI-Hauptform durch, bis die Form, die als Parameter übergeben wurde, gefunden wird. Zusätzlich versehe ich jedes MDI-Child mit einem Tag = 1, wenn es erzeugt wird, da es manchmal zu Problemen kommen kann, wenn die Fenster zur Laufzeit freigegeben werden. Dementsprechend wird dann der Tag wieder auf 0 gesetzt.

Grundsätzlich wird die Form mit BringToFront wieder in den Vordergrund gebracht, wenn es schon existiert. Gab bei mir bisher kein Problem.
colaka Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 200
Erhaltene Danke: 4

Win XP, W7
Delphi 2005 Prof.
BeitragVerfasst: Mo 20.06.11 19:56 
Hallo,

vielen Dank für den Vorschlag, aber die Funktion scheint nur bei MDI-Child-Fenstern zu funktionieren. Ich habe zwar eine MDI-Anwendung, aber dieses eine Fenster, um das es mir geht, ist ein ganz normales, also kein MDI-Child-Fenster.

Vielleicht gibt es doch noch eine Möglichkeit abzufragen, ob ein bestimmtes Formular bereits existiert oder nicht.

Danke Ebi
Lannes
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2352
Erhaltene Danke: 4

Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
BeitragVerfasst: Mo 20.06.11 20:38 
Hallo,

ich denke das Dir Screen.Forms die Möglichkeit bietet.

_________________
MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )