![]() |
MDIChild- wie gehts am besten?
Schönen Guten Morgen,
das ist mein erster Beitrag in das Forum, hoffe das ich alles richtig mache:) Ich habe schon das halbe Internet durchforstet und bin immer noch keinen Schritt weiter. Mein Problem betrifft das Thema MDIChild. Soviel wie ich schon aus diversen Internetseiten erkennen konnte, ist MDIChild nicht ganz ohne- hoffe es findet sich eine einfache Lösung: Mein Vorhaben kurz geschildert: Ich habe ein Hauptformular (form1-fsMDIForm) und weitere Formulare (form2,form3...) die als fsMDIChild definiert sind. Die fsMDIChild-Formulare sollen "im" Hauptformular geöffnet und geschlossen werden können- ich glaube viele Programme wie Microsoft Paint, etc arbeiten ja so. Jede fsMDIChild (form2, form3...) soll etwas anderes beinhalten was ich schon vorher auf den Formularen erstellt habe. In diversen Foren habe ich schon was von "Create(self)" gelesen, ebenso auch über das schließen "Action:= caFree". Ich habe jetzt schon einiges ausprobiert- das Programm stürzt immer wieder ab. Kennt jemand von euch diesbezüglich eine gute Internetadresse oder kennt den Trick? Über eine Antwort würde ich mich sehr freuen- ich blicke momentan da nicht durch. Bedanke mich im vorraus für die Mühe, viele Grüße Alex |
Moin.
Willkommen auf dem Forum. Du bist schon in der Richtung nicht schlech. Mit der
Code:
und mit dem Ereignis OnClose für jedes MDIForm so schreiben:
procedure TForm1.ButtonClick(Sender:Tobject); //Wenn man klickt oder irgend einen Anderen ereignis auslöst.
begin TForm2.Create(Self) end;
Code:
Und übrigens wenn du willst kann ich dir noch zeigen, wie du die Forms(MDI) im Hauptformular ordnen kannst, aber ich bin mir sicher du weist es schon! Wegen Internetseite: tut mir echt leid, kenn einfach keine!
procedure TForm2.FormClose (Sender: Tobject; var Action: TCloseAction);
begin Action:=caFree end; |
Hallo,
schau mal in deinem Delphi-Verzeichnis nach. Üblicherweise sind da Programmbeispiele mit installiert. Soweit ich das aus der Vergangenheit kenne sind immer MDI-Beispiele mit dabei. Die helfen dir mehr wie alles andere. Gruß oki |
Ich habe eine PDF-Datei über MDI-Applicationen (46 Seiten) ist auf der Buch-CD des "Delphi4 Developer's Guide" drauf, ich weiss nicht ob ich sie Dir hier anhängen darf, deshalb zuerst dieser Frage-Tread.
Darf ich diese Datei hier hinein hängen? (Wegen der Legalität und den Rechten...) |
Wenn es das Buch nicht legal im Netz oder sowas ähnliches ist, dann wirst du es wohl nicht dürfen. Da der Autor sicherlich damit auch Geld verdienen will
Aber ich bin sicher man findet sowas ähniches auch mit Google. Oder man schaut einfach mal in die Hilfe |
Zitat:
Die Demo, welche oki ansprach, findest Du im $(DELPHI)\Demos\Doc\TextEdit Verzeichnis. ...:cat:... |
Guten Morgen,
erstmal herzlichen Dank für die schnelle Antworten- wollte schon früher vorbeischauen, habe es aber aus Zeitgründen nicht geschafft. Wie es so bei Delphi ist: Eine Kleinigkeit falsch und ...:-) So war es auch bei dem " TForm2.Create(Self) " ...ich hatte immer das "T" weggelassen! Jetzt funktioniert es wunderbar- jedoch: Bei mehrmaligem aufrufen der Funktion wird auch mehrmals das gleiche Fenster geöffnet- logisch. Ich bräuchte eigentlich jetzt nur noch einen kleinen Tip, wie man überprüft, ob die jeweilige Child-Form geöffnet ist. Darin würde ich den Befehl eingeben, daß die gleiche Childform nicht nochmals geöffnet werden kann. Etwa: If TForm2.create(self)= true...? - Habe das mal ausprobiert- war nix:-) Alternativ könnte ich die Buttons beim erstellen der Form auf Enabled=False stellen...mmmh, würde das aber schon ganz gern mit einem Code überprüfen lassen:) Ich wollte auch noch folgendes loswerden: Schön das es ein Delphiforum gibt, welches einen netten Umgangston beinhaltet! Ich kenne da eins, da trau ich mich ja nicht mal was reinzuschreiben! Aber das nur mal so am Rande:) Besten Dank nochmal- ich denke nach dieser Lösung dürfte das Thema MDIChild bewältigt sein...man ließt sich dann wieder beim nächsten Thema:-))) Schönen Tag euch allen, viele Grüße, Alex |
kleiner Nachtrag:
Ich glaube etwas gefunden zu haben: "if TForm2.Create(self)<> nil..." dürfte etwa schon in die richtige Richtung gehen, jedoch jetzt habe ich das Problem wie ich sage, daß die selbige Form nicht nochmal geöffnet werden soll! Mit "NOT" haut es nicht hin. Danke euch:-) |
Ungetestet, aber das kannst Du ja mal testen :mrgreen:
Delphi-Quellcode:
var
F2: TForm2; I: Integer; begin // FORM2 suchen F2 := nil; for I := 0 to Screen.FormCount - 1 do if (Screen.Forms[I].FormStyle = fsMDIChild) and (Screen.Forms[I] is TForm2) then begin F2 := TForm2(Screen.Forms[I]); Break; end; if F2 = nil then F2 := TForm2.Create(Self) // in F2 ist jetzt der Bezug zum alten bzw. neuen TForm2 Objekt ... end; ...:cat:... |
Moin Lowell,
auch ungetestest, sollte aber auch gehen: Im Gegensatz zu sakuras Beispiel durchsucht dieses direkt nur das Array mit den vorhandenen MDI Child Fenstern.
Delphi-Quellcode:
Da dies als Methode vom Haupformular gemacht ist, muss sie noch dort eingetragen werden :
function TForm1.TForm2AlreadyExists : Boolean;
var i : integer; begin Result := false; for i := 0 to self.MDIChildCount-1 do begin if self.MDIChildren[i] is TForm2 then begin Result := true; exit; end; end; end;
Delphi-Quellcode:
Für weitere TFormx dann analog.
TForm1 = class(TForm)
//.... die übrigen Eintragungen function TForm2AlreadyExists : Boolean private //... end; Mir ist nur noch kein sinnvoller Weg eingefallen, wie man den TFormx Typ als Parameter übergeben kann (auch das müsste irgendwie gehen). |
Frage, geht es auch so, oder gebe ich etwas nicht frei, oder stimmt sonst alles oder weniges nicht?
Delphi-Quellcode:
unit Unit1;
interface uses Windows, Messages, Forms, StdCtrls, ExtCtrls, Dialogs, Classes, Controls, Unit2, Unit3; type TMainForm = class(TForm) PanelBar: TPanel; ButtonShow: TButton; procedure ButtonShowClick(Sender: TObject); procedure FormCreate(Sender: TObject); private Child : TChildForm; procedure CloseChild; { Private-Deklarationen } public { Public-Deklarationen } end; var MainForm : TMainForm; WProc : Pointer; implementation {$R *.DFM} function MyWndProc(Handle : hWnd; Msg, wParam, lParam : longint):longint;stdcall; begin if Msg = Msg_SetToNil then begin MainForm.CloseChild; end; Result := CallWindowProc(WProc,Handle,Msg,wParam,lParam); end; procedure TMainForm.ButtonShowClick(Sender: TObject); begin if Child = nil then begin Child := TChildForm.Create(MainForm); end else begin showMessage('Schon eine ChildForm vorhanden'); end; end; procedure TMainForm.CloseChild(); begin Child := nil; end; procedure TMainForm.FormCreate(Sender: TObject); begin WProc := Pointer(SetWindowLong(Application.Handle,GWL_WNDPROC,Integer(@MyWndProc))); end; end.
Delphi-Quellcode:
unit Unit2;
interface uses Windows, Forms, Unit3; type TChildForm = class(TForm) procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private-Deklarationen } public { Public-Deklarationen } end; var ChildForm: TChildForm; implementation {$R *.DFM} procedure TChildForm.FormClose(Sender: TObject; var Action: TCloseAction); begin SendMessage(Hnd,Msg_SetToNil,0,0); Action := caFree; end; end.
Delphi-Quellcode:
unit Unit3;
interface uses Messages, Forms, Windows; var hnd : THandle; const Msg_SetToNil = WM_USER+100; implementation initialization hnd := Application.Handle; end. Also Unit1 beinhaltet die MDIForm, Unit2 die MDIChildForm und Unit3 Globales. (Ps. Wenn der Code zu lang ist, lösche ich ihn wieder.) Danke für antworten, Mirilin |
Moin Mirlin,
soweit ich das überblicke wird wieder alles freigegeben: Dadurch, dass Du beim Create MainForm als Owner angibst, würde das ChildForm spätestens beim zerstören (freigeben) von Mainform mit freigegeben werden. Durch Action := caFree wird es dann beim Schliessen auch wieder freigegeben. Das mit der WindowProcedure kannst Du auch einfacher haben:
Delphi-Quellcode:
Falls da sonst nichts drin ist, könnten nun die FormCreate und CloseChild entfallen.
// Unter FormCreate in TMainForm = class(TForm)
procedure WndProc(var msg: TMessage); override; // In Implementation procedure TMainForm.WndProc(var msg: TMessage); begin if Msg = Msg_SetToNil then begin Child := nil; exit; // Die "normale" WndProc kennt die Message ja sowieso nicht end; inherited WndProc(msg); end; |
Hallo zusammen...
schaut euch mal dies an- funzt einwandfrei!
Delphi-Quellcode:
Es gibt einen Unterschied:
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, Menus, StdCtrls; type TForm1 = class(TForm) MainMenu1: TMainMenu; StatusBar1: TStatusBar; N11: TMenuItem; N21: TMenuItem; Button1: TButton; procedure N11Click(Sender: TObject); procedure N21Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation uses Unit2, Unit3; {$R *.dfm} procedure TForm1.N11Click(Sender: TObject); begin If not Assigned(Form2) then Form2:=TForm2.Create(Application); end; procedure TForm1.N21Click(Sender: TObject); begin If not Assigned(Form3) then begin Form3:=TForm3.Create(Application); end else Freeandnil(Form3); end; end. Form drei wird mit selbigen Button der sie aufruft auch wieder geschlossen. Bei Form eins muß man wie gewohnt (über das "X") schließen. Probiert es mal aus- bei mir klappts einwandfrei. OH- bevor ich es vergesse- wichtig: In der Unit der jeweiligen Forms wie gewohnt:
Delphi-Quellcode:
und nicht vergessen:
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin Action:=caFree end;
Delphi-Quellcode:
...sonst gibts wieder Fehlermeldungen!
procedure TForm2.FormDestroy(Sender: TObject);
begin Form2 := nil; end; Also, danke euch nochmal!!! Bis bald, Grüße Alex...der bestimmt bald wieder was textet;-) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:00 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz