Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Menü dynamisch aufbauen


Bronstein - Fr 09.03.07 19:05
Titel: Menü dynamisch aufbauen
Wie würdet ihr so ein Menü aufbauen, damit man alles in einer ini-Datei einstellen kann:

Link1
Link1.1
Link1.1.1
Link1.1.2
Link1.2
Link1.2.1
Link1.2.2
Link1.2.3
Link2
...


Weiß einfach niccht wie ich das lösen könnte.
Wie man Labels zu Laufzeit erstellt weiß ich ja.


jakobwenzel - Fr 09.03.07 19:07

Ich würd jeden Eintrag mit ner eindeutigen Nummer versehen und immer noch die Nummer des übergeordneten Eintrags (oder eben für Top-Level-Einträge eine in jedem Fall ungültige Nummer) speichern. :wink:


Christian S. - Fr 09.03.07 19:18

Ich verstehe die Frage nicht ganz. Willst Du ein Menü dynamisch erzeugen? Das geht so:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
var
  aItem, subItem, subSubItem : TMenuItem;
begin
  aItem := TMenuItem.Create(self);
  aItem.Caption := 'Eintrag 1';
  MainMenu1.Items.Add(aItem);

  subItem := TMenuItem.Create(self);
  subItem.Caption := 'Eintrag 1.1';
  aItem.Add(subItem);

  subSubItem := TMenuItem.Create(self);
  subSubItem.Caption := 'Eintrag 1.1.1';
  subItem.Add(subSubItem);

  subItem := TMenuItem.Create(self);
  subItem.Caption := 'Eintrag 1.2';
  aItem.Add(subItem);

  subItem := TMenuItem.Create(self);
  subItem.Caption := 'Eintrag 1.3';
  aItem.Add(subItem);


jakobwenzel - Fr 09.03.07 19:21

Ich hab das jetz so verstanden, dass er eine Liste mit beliebig tief verschachtelten Unterpunkten hat und diese jetzt in eine INI-Datei abspeichern will.
Dafür eignet sich dann meine Lösung weiter oben. :wink:


Bronstein - Fr 09.03.07 19:21

Ich möchte einfach ein flexibles menü erstellen mit einer unbestimmten anzahl an Untermenüs.

Das Menü möchte ich komplett in einer INI-Datei konfigurieren.

Später sollen dann zum entsprechenden Menüeintrag Bilder angezeigt werden


Bronstein - Fr 09.03.07 19:47

Ich meine das so wie jakobwenzel geschrieben hat.

Ich dachte mir die INI-Datei könnte so aussehen:

[Link]
Anzahl=2

[Link1]
Name=Menü1
[Link1.1]
Name=Beschriftung1.1
Bild=bild1_1.jpg

Link[1.2]
Name=Beschriftung1.2
Bild=bild1_2.jpg



[Link2]
Name=Menü2
[Link2.1]
Name=Beschriftung2.1
Bild=bild2_1.jpg

Link[2.2]
Name=Beschriftung2.2
Bild=bild2_2.jpg

Link[3.2]
Name=Beschriftung3.2
Bild=bild3_2.jpg



Wie ich das jetzt aber programmtechnisch umsetzen kann weiß ich nicht so recht


Billi Berserker - Fr 09.03.07 19:50

Ich würde das ganze über XML gestalten und das laden dann mit ensprechenden rekusiven funktionsaufrufen implementieren.

in xml würde das so aussehen:

XML-Daten
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
<menu>
  <item>
    <caption>123</caption>
    <icon>c:\1.bmp</icon>
  </item>
  <item>
    <caption>Eintrag mit Untermenü</caption>
    <icon>c:\2.bmp</icon>
    <items>
      <item>
         <caption>123</caption>
         <icon>c:\4.bmp</icon>
      </item>
      <item>
        <caption>123</caption>
        <icon>c:\5.bmp</icon>
      </item>
    </items>
  </item>
  <item>
    <caption>ghj</caption>
    <icon>c:\3.bmp</icon>
  </item>
</menu>


Lannes - Fr 09.03.07 19:53

Hallo,

bau Dir doch die ini so auf:

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:
[RootItems]
RootItemsCount = 2
Item1 = Link1
Item2 = Link2

[Link1]
ItemsCount = 2
Item1 = Link1.1
Item2 = Link1.2 

[Link1.1]
ItemsCount = 2
Item1 = Link1.1.1
Item2 = Link1.1.2 
Item1Pfad = d:\hjashk.jpg
Item2Pfad = d:\kpk45.jpg
 
[Link1.2]
ItemsCount = 3
Item1 = Link1.2.1
Item2 = Link1.2.2 
Item3 = Link1.2.3 
Item1Pfad = d:\aaa.jpg
Item2Pfad = d:\xxxx.jpg 
Item3Pfad = d:\yyyy.jpg

Dann kannst Du die ini auslesen und das Menü erzeugen, eventuell auch rekursiv.
Die Section [RootItems] liefert Dir die Bezeichnung der Untermenü-Sectionen.
Also 'Item1 = Link1' = Section [Link1] usw. ...


Bronstein - Fr 09.03.07 19:58

@Billi Berserker

Kann ich so eine XML-Datei in mein Delphi-Projekt einbinden, wie funktioniert so was. Habe ich noch nie gehört. Vielleiht kennst du ja ein Tutorial


Marco D. - Fr 09.03.07 20:00

user profile iconBronstein hat folgendes geschrieben:
@Billi Berserker

Kann ich so eine XML-Datei in mein Delphi-Projekt einbinden, wie funktioniert so was. Habe ich noch nie gehört. Vielleiht kennst du ja ein Tutorial

Würde dir lieber zu der Ini-Datei raten. ;) Das ist imho einfacher zu implementieren.


Billi Berserker - Fr 09.03.07 20:09

Das ganze über ne .ini Datei zu machen halte ich für selbstmord :)
Einfach nur unübersichtlich und bäää ;)


Für XML gibts es ne menge Komponenten um die Dateien zu laden und zu benutzen.
Ich benutze TJvSimpleXML welche bei JVCL dabei ist.
Keine Ahnung obs dazu tutorials gibt, aber die benutzung is eigentlich recht einfach - wenn man ein wenig damit rum gespielt hat dann gehts irgendwann ;)

Beispiel (ungetestet):

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:
var
  XML : TJvSimpleXML;
  n : integer;
  name : String;
  icon : String;
begin
  XML := TJvSimpleXML.Create(nil);
  try
    XML.LoadFromFile('C:\MyMenu.xml');
    for n := 0 to XML.Root.Items.Count - 1 do
        with XML.Root.Items.Item[n].Items do
        begin
          // Die daten für jedes menü item im Hauptmenü
          name := Value('Name');
          icon := Value('Icon');
          if ItemNamed['items'] <> nil then
             with ItemNamed['items'].Items do
             begin
               // es gibt unterpunkte, mach irgendwas damit
             end;         
        end;
  finally
    XML.Free;
  end;
end;

für das laden von den unterpunkten müßte man eine rekursive funktion schreiben welche das Ziel Menü und den übergeordneten Knoten als parameter nimmt...


Bronstein - Fr 09.03.07 22:36

Habe das jetzt mit einer INI-Datei von Lannes umgesetzt.

Jetzt habe ich aber ein Problem. Wenn ich auf ein Label klicke möchte ich den Namen des Labels bekommen. Leider ist die Msg aber leer.

Habe mal das komplette Projekt im Anhang. Keine Ahnung warumm das nicht geht.


Christian S. - Fr 09.03.07 22:43

Das ist ein neues, anderes Problem. Bitte erstelle dafür einen neuen Thread.

Sollten noch Nachfragen zu diesem Problem auftauchen, melde den Thread ans Team und wir öffnen ihn wieder.

//edit: Hier [http://www.delphi-forum.de/viewtopic.php?p=425442#425442] geht es weiter