Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - MDIChild / MDIForm manipulieren / verändern ???


Dhakiyah - Do 16.07.09 16:34
Titel: MDIChild / MDIForm manipulieren / verändern ???
Hallo!
Habe folgendes Problem.
Ich möchte in einem Hauptformular ein anderes öffnen.
Verwende ich MDIChild öffnet er es zwar im Hauptformular, aber ich kann 1000 andere öffnen, das will ich vermeiden.
Verwende ich MDIForm dann kann ich zwar nur ein Fenster öffnen, was ich schließen muss, damit ich ein anderes öffnen kann, aber dieses erscheint in einem extra Fenster.
Wie bekomme ich das Problem hin.
Ich möchte das immer nur EIN Fenster im Hauptformular offen ist. Öffne ich ein zweites, soll das erste AUTOMATISCH geschlossen werden und das zweite Fenster erscheint.
Geht das irgendwie?
Wenn ja, wie?

LG
Jasmin


Martok - Do 16.07.09 16:39

Ähm, ja... disable doch einfach alles was neue Fenster öffnet :?:

Oder, wenn du sie schließen willst: MDIChildren/MDIChildCount. Da hat die DOH sogar gleich Code mit dabei:

DOH hat folgendes geschrieben:
In diesem Beispiel werden alle untergeordneten MDI-Fenster von Form1 geschlossen.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
var
  I: Integer;
begin
  with Form1 do
    for I := MDIChildCount-1 downto 0 do
      MDIChildren[I].Close;

end;


Dhakiyah - Do 16.07.09 16:41

Und wo genau muss dieser Code hin?
Ins Hauptformular oder in das Formular selbst?

LG
Jasmin


Renegade - Do 16.07.09 16:43

Du musst einfach vor dem öffnen eines Fensters prüfen ob schon eines geöffnet ist. Wenn das der Fall ist schließt du das geöffnete bevor du das neue öffnest. Der Code steht oben.


Martok - Do 16.07.09 16:44

Naja, wenn du die andern Formulare schließen willst, wenn ein neues aufgemacht wird... schätzen sie mal ;)

{Here be more text, aber den hat user profile iconRenegade jetzt schon vorweggenommen.}


Dhakiyah - Fr 17.07.09 09:32

Geht nicht...

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure TForm1.Gleitzeitantrag1Click(Sender: TObject);
begin
  with Form1 do
    for I := MDIChildCount-1 downto 0 do
      MDIChildren[I].Close;
  Application.Initialize;
  Application.CreateForm(TForm6, Form6);
  Application.Run;
end;



:bawling: :bawling: :bawling:


Xentar - Fr 17.07.09 09:49

Können wir uns vielleicht darauf einigen, dasss die Geschichte nur noch in EINEM der beiden Threads weiter geht? Da das mit dem Mainmenu http://www.delphi-forum.de/viewtopic.php?t=93509 nichts mehr zu tun hat, würde ich vorschlagen, dass es hier weiter geht.

Zu deinem Problem:
Was tust du da????
Wieso initialisiert du jedesmal die Anwendung neu, und rufst jedesmal Run auf?!
Du solltest nicht einfach irgendeinen Quellcode aus der Projektdatei kopieren, ohne zu wissen, was der überhaupt macht.


Eigentlich solltest es doch reichen, wenn du

Delphi-Quelltext
1:
<meinFormular>.Show;                    

aufrufst, und vorher mit der Schleife alle anderen Fenster schließt.


Dhakiyah - Fr 17.07.09 09:51

Ich weiß nicht, ob ihr das mitbekommen habt, aber ich bin ne Azubine und kann noch nicht richtig programmieren, also weiß ich im Grunde nach nicht, was ich da tue... DANKE !!!

Und eure Antworten sind so knapp, dass ich damit nichts anfangen kann... SORRY...
Ich frage wie mache ich das mit dem TMainMenue und dann kommt nur nimm TPageControl...

Wie backe ich einen Kuchen? Nimm Zucker... SUUUUUUUUUUUUUUUUPER...

Ich habe es jetzt so geregelt und weiß nix anderes... Zumindest gehts...


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:
43:
44:
45:
46:
47:
48:
49:
procedure TForm1.Gleitzeitantrag1Click(Sender: TObject);
begin
  with Form1 do
    for I := MDIChildCount-1 downto 0 do
      MDIChildren[I].Close;
  Application.Initialize;
  Application.CreateForm(TForm6, Form6);
  Application.Run;
end;

procedure TForm1.Kalender1Click(Sender: TObject);
begin
  with Form1 do
    for I := MDIChildCount-1 downto 0 do
      MDIChildren[I].Close;
  Application.Initialize;
  Application.CreateForm(TForm2, Form2);
  Application.Run;
end;

procedure TForm1.Protokoll1Click(Sender: TObject);
begin
  with Form1 do
    for I := MDIChildCount-1 downto 0 do
      MDIChildren[I].Close;
  Application.Initialize;
  Application.CreateForm(TForm3, Form3);
  Application.Run;
end;

procedure TForm1.Urlaubsantrag1Click(Sender: TObject);
begin
  with Form1 do
    for I := MDIChildCount-1 downto 0 do
      MDIChildren[I].Close;
  Application.Initialize;
  Application.CreateForm(TForm4, Form4);
  Application.Run;
end;

procedure TForm1.Zeitnachtrag1Click(Sender: TObject);
begin
  with Form1 do
    for I := MDIChildCount-1 downto 0 do
      MDIChildren[I].Close;
  Application.Initialize;
  Application.CreateForm(TForm5, Form5);
  Application.Run;
end;


Xentar - Fr 17.07.09 10:01

Mkay, also nehmen wir mal das hier als Beispiel:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure TForm1.Gleitzeitantrag1Click(Sender: TObject);
begin
  with Form1 do
    for I := MDIChildCount-1 downto 0 do
      MDIChildren[I].Close;
  Application.Initialize;
  Application.CreateForm(TForm6, Form6);
  Application.Run;
end;


das sollte eigentlich auch so funktionieren:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
procedure TForm1.Gleitzeitantrag1Click(Sender: TObject);
begin
  for I := MDIChildCount-1 downto 0 do
    MDIChildren[I].Close;
  Form6.Show;
end;


Dhakiyah - Fr 17.07.09 10:07

Ne... Geht nicht...
Kommt eine Fehlermeldung:
Zugriffsverletzung ..................

LG
Jasmin


Xentar - Fr 17.07.09 10:12

Dann schau mal unter Projekt -> Optionen -> Formulare.
Der Einfachheit halber, sollten hier erstmal alle Formulare auf der linken Seite, unter "Automatisch erzeugen" stehen.

Braucht zwar etwas mehr Speicher, aber ist für den Anfang wesentlich einfacher.


Dhakiyah - Fr 17.07.09 10:15

Geht auch nicht.
Jetzt zeigt er mir die Seite nicht an und schließt nur einfach alle...


Xentar - Fr 17.07.09 10:48

- Hast du dein Hauptformular noch als fsMDIForm, und das Form6 als fsMDIChild?
- Ist auf deinem Hauptformular noch Platz frei, oder alles belegt, z.B. von einem Panel?

Ansonsten würde ich bitten, doch mal das Projekt, als ZIP Datei, anzuhängen (ohne die exe).


Dhakiyah - Fr 17.07.09 10:55

Ja, hab ich.


Dhakiyah - Mo 20.07.09 10:25

Ich machs jetzt nach Absprache mit meinem Ausbilder so:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure Tfrm_mdi_main.Protokoll1Click(Sender: TObject);
var i: integer;
begin
  with frm_mdi_main do
    for I := MDIChildCount-1 downto 0 do
      MDIChildren[I].Close;
  Application.CreateForm(Tfrm_mdi_protokoll, frm_mdi_protokoll);
  Application.Run;
end;


LG
Jasmin


SvenAbeln - Mo 20.07.09 13:45

user profile iconDhakiyah hat folgendes geschrieben Zum zitierten Posting springen:
Ich machs jetzt nach Absprache mit meinem Ausbilder so:


Das muß ja ein toller Ausbilder sein :lol:

1. Das with ist unnötig, da du innerhalb der Klasse auf eigene Eigenschaften zugreifst, in deinem Fall würden alle Objekte der Klasse Tfrm_mdi_main immer nur auf einer einzigen globalen Variable arbeiten.

2. Application.Run hat dort NICHTS zu suchen. Die Application wird nur einmal gestartet und läuft bis zum Ende. Es gibt keinen Grund die Application mehrmals zu starten, es kann sogar zu einigen Fehlern oder komischen Efekten führen.
Ausserdem enthält Applicarion.Run eine Schleife, die erst beim Ende des Programms verlassen wird, d.h. alles was in deiner Funktion Protokoll1Click hinter dem Application.Run stehen sollte wird auch erst zum Programmende ausgeführt.

3. Mußt du aufpassen, das du die Fenster auch irgendwo wieder frei gibst.
Im Moment erzeugt jeder Aufruf von Tfrm_mdi_main.Protokoll1Click ein neues Fenster und setzt es auf die eine globale Variable frm_mdi_protokoll. So kannst du dir schnell eine Menge Memoryleaks erschaffen.


So sollte es auch funktionieren


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
procedure Tfrm_mdi_main.Protokoll1Click(Sender: TObject);
var i: integer;
begin
  for I := MDIChildCount-1 downto 0 do
    MDIChildren[I].Close;
  Application.CreateForm(Tfrm_mdi_protokoll, frm_mdi_protokoll);
end;


Dhakiyah - Mo 20.07.09 14:03

Zu 3:

Ich habe in der Form folgendes gemacht:


Delphi-Quelltext
1:
2:
3:
4:
5:
procedure Tfrm_mdi_protokoll.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  Action := caFree;
end;