| Autor |
Beitrag |
Morpheus1572
      
Beiträge: 157
Win XP
Delphi 7
|
Verfasst: Di 10.03.09 19:26
Ich weiß nicht ob ich hier richtig bin aber wo sonst wenn nicht hier???
Mein Problem:
ich habe bisher noch nicht verstanden wie ich das mit dem menü meines programmes deixel. zum verständnis ein einfaches beispiel:
1. Programm startet es ist das hauptfenster zu sehen mit der menüleiste.
2. ich wähle vom ersten menüpunkt den ersten punkt aus, es öffnet sich ein kindfenster in dem ich nun irgendwas arbeite. gleichzeitig deaktiviere ich den entsprechenden eintrag im menü, damit dieses kindfenster nicht noch mal aufgerufen werden kann!
so weit alles chick.
3. wenn ich nun z.b. vom ersten menüpunkt den den zweiten (unter)punkt anklicke soll das erste kindfenster geschlossen werden und das zweite geöffnet. gleichzeitig müssen natürlich die entsprechenden einträge im menü de- bzw. aktiviert werden. woher weiß jedoch der neu aufgerufene menüpunkt, welches kindfenster zu schließen ist, und dass dessen eintrag im menü deaktivert werden muss??? ??? ???
und 4.
wenn ich zb. das erste kindfenster schließe, kann ich mir merken (also das programm logischer weise) an welcher stelle einer auflistung z.b. es zum zeitpunkt des schließens war?
Punkt 4 ist eher unwichtig, aber das verständnis von punkt 3 ist mir sehr wichtig.
Thx an alle geduldigen. Morph.
|
|
jaenicke
      
Beiträge: 19341
Erhaltene Danke: 1752
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Di 10.03.09 19:32
Du kannst alle geöffneten Kindfenster durchgehen. Du kannst auch schauen was es für ein Kindfenster ist. Das geht so: Delphi-Quelltext 1: 2: 3:
| for i := 0 to MDIChildCount - 1 do if MDIChildren[i] is TfrmChild1 then ... | Am sinnvollsten wäre vermutlich eine eigene Klasse zur Fensterverwaltung. So habe ich das gehandhabt.
|
|
Morpheus1572 
      
Beiträge: 157
Win XP
Delphi 7
|
Verfasst: Di 10.03.09 19:39
danke jaenicke. das mit den klassen habe ich noch so gar nicht gerafft, also lasse ich davon erstmal die fingerchen, bis ich soweit bin  (ich weiß ich weiß, ist sträflich und wie kann man nur so programmieren).
also klasse ist erst mal nicht, dann werde ich das mal mit der entsprechenden routine machen aber kannst du mir kurz noch erklären was deine if-zeile gerade macht und wie ich dann die entsprechenden menüeinträge verändere?
interessant finde ich, dass man offenbar alles zählen kann, selbst MDIChilds... bin begeistert und lerne ständig dazu, wobei mir das immer wieder zeigt wie weit ich noch weg bin von meinem ziel mich wieder programmierer nennen zu dürfen...
Morph.
|
|
jaenicke
      
Beiträge: 19341
Erhaltene Danke: 1752
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Di 10.03.09 19:44
Die if-Abfrage sieht nach, welchen Typ das aktuelle Child in der Schleife hat. Denn du hast ja verschiedene Typen nehme ich an, oder?
Die Menüeinträge könntest du z.B. beim Öffnen des Kindfensters an dieses übergeben. beim Schließen kannst du es dann dort einfach auslesen. 
|
|
Morpheus1572 
      
Beiträge: 157
Win XP
Delphi 7
|
Verfasst: Di 10.03.09 19:50
ganz ehrlich? ich verstehe nur bahnhof. werde wohl mal herumdoktern müssen...
verschiedene typen??? warum? und wenn ja welche? meinst du damit das FormStyle? gott mein programm läuft soweit sauber und nun komme ich dazu mich mit dem blöden menü zu beschäftigen und raff nix.
gibt es nen tut dazu oder darüber, oder ist es einfach nur super einfach und ich seh den wald vor lauter bäumen nicht?
|
|
jaenicke
      
Beiträge: 19341
Erhaltene Danke: 1752
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Di 10.03.09 19:56
Dann zeig doch einfach einmal den Code, mit dem du die Kindfenster erstellst.
Mit verschiedenen Typen meine ich, dass du ja vermutlich für verschiedene Aufgaben auch verschiedene Kindfenster hast. Einmal meinetwegen mit einem Memo, einmal mit ein paar Edits oder so. Also eben verschiedene Formulare.
Denn wenn jedes Formular genauso aussehen würde, dann bräuchtest du ja nicht mehrere Kindfenster.
|
|
Morpheus1572 
      
Beiträge: 157
Win XP
Delphi 7
|
Verfasst: Di 10.03.09 20:50
stimmt. okay. also ich benutze verschieden fenster für verschiedene aufgaben.
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| procedure THauptformular.bearbeiten1Click(Sender: TObject); begin Panel1.Visible:=false; bearbeiten1.Enabled:=False; TForm3.Create(Self); end; |
und so rufe ich es einfach auf... das panel1 schalte ich "aus", weil es durch das Kindfenster "durchscheint" (also einige komponenten).
mehr mache ich nicht. und das eben bei jedem kindfenster...
|
|
jaenicke
      
Beiträge: 19341
Erhaltene Danke: 1752
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Di 10.03.09 21:20
Dann könntest du das so machen: Delphi-Quelltext 1: 2: 3:
| Form3 := TForm3.Create(Self); Form3.MenuEntry := (Sender as TMenuItem); (Sender as TMenuItem).Enabled := False; | MenuEntry müsstest du innerhalb von TForm3 als public definieren, entweder als normales Feld ( MenuEntry: TMenuItem;) oder als Property.
Wenn du das Array MDIChildren durchgehst, dann kannst du darauf zugreifen: Delphi-Quelltext 1: 2: 3:
| for i := 0 to MDIChildCount - 1 do if MDIChildren[i] is TForm3 then TForm3(MDIChildren[i]).MenuEntry.Enabled := True; |
|
|
Morpheus1572 
      
Beiträge: 157
Win XP
Delphi 7
|
Verfasst: Di 10.03.09 21:37
okay, dann probiere ich das mal. wenn ich nicht weiterkomme melde ich mich sicher wieder. 
|
|
Morpheus1572 
      
Beiträge: 157
Win XP
Delphi 7
|
Verfasst: Fr 13.03.09 16:27
okay, das prinzip habe ich verstanden... ABER:
wo setze ich denn dann die IF-Abfrage ein??? im create vom entsprechend aufgerufenen Form oder wo?
ich habe jetzt folgendes gemacht:
1. das Form1 ist das <Hauptformular>. darin habe ich die globale variable gesetzt. von hier aus wird z.b. das form3 aufgerufen. den aufruf habe ich mit deinen drei zeilen erweitert (genau genommen sind es ja nur 2 zeilen).
Dabei muss ich sagen, dass ich es nicht ganz so übernehmen konnte. bei Form3.MenuEntry motzt er rum. beim weglassen von Form3. funzt es...
2. jetzt weiß ich nicht mehr weiter...
Morph.
|
|
Morpheus1572 
      
Beiträge: 157
Win XP
Delphi 7
|
Verfasst: So 15.03.09 14:04
|
|
jaenicke
      
Beiträge: 19341
Erhaltene Danke: 1752
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 15.03.09 18:29
Also wenn es nur darum geht den Menüpunkt wieder zu aktivieren, dann kannst du auch (wenn du MenuEntry in dem entsprechenden Kindformular beim Aufrufen gesetzt hast) in OnClose des Kindformulars schreiben: Delphi-Quelltext 1:
| MenuEntry.Enabled := True; | Ich glaube du hast aber MenuEntry in deinem Hauptformular statt dem Kindformular deklariert, oder?
|
|
Morpheus1572 
      
Beiträge: 157
Win XP
Delphi 7
|
Verfasst: So 15.03.09 18:55
jep habe ich. und zwar als globale variable.
warum, war das falsch?
|
|
jaenicke
      
Beiträge: 19341
Erhaltene Danke: 1752
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 15.03.09 19:00
Es geht doch gerade darum, dass du in dem Kindfenster die Information brauchst mit welchem Menüeintrag das Fenster geöffnet wurde. Solange immer nur ein Fenster offen ist, kann das auch im Hauptfenster liegen, dann kannst du jeweils vor dem Öffnen des neuen Fenster den alten Menüeintrag aktivieren.
Allerdings sehe ich nicht so recht den Sinn, wenn wirklich nur immer ein Kindfenster angezeigt wird. Bei MDI geht es doch gerade darum, dass mehrere gleichzeitig angezeigt werden. Das Einblenden von nur einem Fenster geht ja auch viel einfacher, außerdem braucht man dafür eigentlich ja nicht mehrere Formulare, wenn nur bestimmte Komponenten(gruppen) ausgewechselt werden sollen. 
|
|
Morpheus1572 
      
Beiträge: 157
Win XP
Delphi 7
|
Verfasst: So 15.03.09 20:51
ist soweit ja richtig.
aber im späteren verlauf sollen ja auch mehrere fenster aufgemacht werden können und dann stehe ich halt da mit meinem latein...
derzeit brauche ich das nicht aber in ein paar tagen schon. deswegen habe ich ja den Thread hier eröffnet. und nun bin ich noch mehr verwirrt.
wo müsste ich also was genau eintragen um mein gewünschtes ziel zu erreichen? (für später - also in ein paar tagen...)
Morph.
|
|
jaenicke
      
Beiträge: 19341
Erhaltene Danke: 1752
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 15.03.09 22:24
Wenn mehrere Fenster geöffnet werden sollen gleichzeitig, dann vielleicht noch abhängig davon welche anderen gerade offen sind usw., dann würde ich eine eigene Verwaltungsklasse schreiben. Dann kannst du diese ganze Logik komplett dorthin verkagern und hast das nicht mehr so mit der Oberfläche verknüpft.
Wenn dann ein Menü aufgeklappt wird, dann schaust du in OnPopup welche der Menüeinträge des Menüs aktiviert sein sollen und welche nicht. Danach kannst du dich dann bei der Fensterverwaltungsklasse erkundigen. Genauso übergibst du bei Menüaktionen das Anzeigen / Schließen von Fenstern auch an diese Klasse.
So kannst du das alles an einem Ort programmieren ohne die logische Steuerung der Oberfläche über die ganze Oberfläche zu verteilen.
|
|
Morpheus1572 
      
Beiträge: 157
Win XP
Delphi 7
|
Verfasst: Mo 16.03.09 03:43
oki, klingt sehr kompliziert. dann werde ich mich mal mit klassen beschöftigen müssen und hoffe, dass ich das raffe. danke schon mal für die denkanstöße ich werde dich auf dem laufenden halten...
|
|
jaenicke
      
Beiträge: 19341
Erhaltene Danke: 1752
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mo 16.03.09 15:55
Im Gegenteil, das macht es sogar einfacher.
Ich habe dabei die Tag-Eigenschaft der Menüeinträge für die Kennzeichnung von deren Funktion benutzt, d.h. die habe ich direkt im Objektinspektor zugewiesen. So brauchte ich nur ein OnClick für alle, die mit der Verwaltungsklasse verbunden waren: Delphi-Quelltext 1: 2: 3: 4: 5:
| procedure MenuItemClick(Sender: TObject); begin if Sender is TMenuItem then WindowManager.ExecuteAction(TMenuItem(Sender).Tag); end; | Und dort habe ich dann Konstanten benutzt, die die selben Werte wie die Menüeinträge hatten: Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| procedure TWindowManager.ExecuteAction(ActionID: Integer); begin case ActionID of ACI_EDITWINDOW: begin ... frmEditWindow.Show; ... end; ACI_NEWWINDOW: ... else raise Exception.Create(... end; end; | Und in OnPopup eines übergeordneten Menüeintrags gehst du alle Untereinträge durch: Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7:
| var i: Integer; begin if Sender is TMenuItem then for i := 0 to TMenuItem(Sender).Items.Count - 1 do TMenuItem(Sender).Enabled := WindowManager.IsActionEnabled( TMenuItem(Sender).Items[i].Tag); | In IsActionEnabled kannst du dann mit case wieder alles unterscheiden.
Dies ist jetzt nicht meine Implementierung, die war etwas anders, aber das Prinzip wird so denke ich deutlich. Nebenbei gäbe es auch noch den ActionManager und Actions in Delphi selbst, das wäre auch noch zusätzlich eine Möglichkeit. Dann bräuchte es auch keine Tag-Eigenschaft zur Identifizierung des Eintrags.
|
|