Menu dynamisch



  • Hallo zusammen

    Im Forum habe ich diesen für mich sehr interessanten Code gefunden, den ich für mich angepasst habe. Die Namen für das Menu kommen aus einer Ini-Datei und die Bilder nehme ich aus dem Programm-Ordner. Somit kann ich wenn ich das Programm fertig habe, die Bilder austauschen und die Menüeinträge ändern ohne das Programm neu zu compilieren.

    Im header: #include "IniFiles.hpp"

    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
    TIniFile *ini;
    
    AnsiString workpath=ExtractFilePath(Application->ExeName); //sucht Pfad
    ini = new TIniFile(workpath+"test.ini");  //datei test im selben Ordner
    
    MainMenu->Images    = NULL;        // keine ImageList verwenden
       MainMenu->OwnerDraw = false;    
    
       TMenuItem *Menu      = new TMenuItem(this);
       TMenuItem *SubMenu1  = new TMenuItem(this);
       TMenuItem *Sep       = new TMenuItem(Menu);
       TMenuItem *SubMenu2  = new TMenuItem(Menu);
    
       Menu->AutoLineReduction = maAutomatic; // entfernt überflüssige Trennstriche
       Menu->Caption        = "Datei";
    
       SubMenu1->Caption = ini->ReadString   ("myForm", "1001", "dummy");
       SubMenu1->Bitmap->LoadFromFile("pic/101.bmp"); //bmp aus ordner pic
    
       Sep->Caption         = "-";
    
       SubMenu2->Caption = ini->ReadString   ("myForm", "1002", "dummy");
       SubMenu2->Bitmap->LoadFromFile("pic/101.bmp"); //bmp aus ordner pic
    
       MainMenu->Items->Insert(0, Menu);
       Menu->Insert(0, SubMenu1);
       Menu->Insert(1, Sep);
       Menu->Insert(2, SubMenu2);
    }
    

    Nun zu meinem Problem: ( Ist für mich noch zu schwierig)

    Wie aber erstelle ich eine Erweiterung des Menüs nach rechts und das wieder mit zwei SubMenüs, und schlussendlich den Klickevent zur Ansteuerung der Daten die ich Aufrufen kann. Hier im Beispiel mit einfachen MessageBoxen??

    Kann mir da jemand unter die Arme greifen und helfen. Ich hänge schon Wochen am selben herum und komme nicht weiter.

    Gruss Thomas



  • TMenuItem* item1 = new TMenuItem(MainMenu1);
    item1->Caption = "menü";

    TMenuItem* item2 = new TMenuItem(item1);
    item2->Caption = "sub menü";

    TMenuItem* item3 = new TMenuItem(item2);
    item3->Caption = "sub menü 1";

    TMenuItem* item4 = new TMenuItem(item2);
    item4->Caption = "sub menu 1";

    MainMenu1->Items->Add(item1);
    item1->Add(item2);
    item2->Add(item3);
    item2->Add(item4);



  • Danke Maverick

    Ich habe das ganze mal so gelöst, war ja nicht sauber formuliert von mir.

    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
    TMenuItem* item1 = new TMenuItem(MainMenu1);
    item1->Caption = "menü";
    TMenuItem* item2 = new TMenuItem(item1);
    item2->Caption = "menü 1";
    TMenuItem* item3 = new TMenuItem(item2);
    item3->Caption = "menü 2";
    TMenuItem* item4 = new TMenuItem(item2);
    item4->Caption = "menü 3";
    
    MainMenu1->Items->Add(item1);
    item1->Add(item2);
    item1->Add(item3);
    item1->Add(item4);
    
    TMenuItem* item11 = new TMenuItem(MainMenu1);
    item11->Caption = "spez";
    TMenuItem* item12 = new TMenuItem(item1);
    item12->Caption = "menü 4";
    TMenuItem* item13 = new TMenuItem(item2);
    item13->Caption = "menü 5";
    TMenuItem* item14 = new TMenuItem(item2);
    item14->Caption = "menü 6";
    
    MainMenu1->Items->Add(item11);
    item11->Add(item12);
    item11->Add(item13);
    item11->Add(item14);
    }
    

    Finde den Aufbau gut und für mich logisch nachvollziehbar.

    Was mir jetzt noch fehlt, sind die Clickevents zur Verarbeitung der Menüpunkte

    Gruss Thomas



  • Hallo

    Siehe FAQ hier im Forum, Abschnitt Komponenten benutzen, Beitrag zur Laufzeit erstellen, anzeigen und Events zuweisen

    bis bald
    akari



  • akari schrieb:

    Hallo

    Siehe FAQ hier im Forum, Abschnitt Komponenten benutzen, Beitrag zur Laufzeit erstellen, anzeigen und Events zuweisen

    bis bald
    akari

    Hast du für solche posts schon templates ? 😛



  • Das fertige Programm:

    //---------------------------------------------------------------------------
    class TForm1 : public TForm
    {
    __published:	// Von der IDE verwaltete Komponenten
          TMainMenu *MainMenu1;
          void __fastcall FormCreate(TObject *Sender);
    private:	// Anwender-Deklarationen
          void __fastcall TForm1::OnClick1(TObject *Sender);
          void __fastcall TForm1::OnClick2(TObject *Sender);
          void __fastcall TForm1::OnClick3(TObject *Sender);
          void __fastcall TForm1::OnClick4(TObject *Sender);
    public:		// Anwender-Deklarationen
               __fastcall TForm1(TComponent* Owner);
    };
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
    TMenuItem* item1 = new TMenuItem(MainMenu1);
    item1->Caption = "menü";
    
    TMenuItem* item2 = new TMenuItem(item1);
    item2->Caption = "menü 1";
    item2->OnClick = OnClick1;        //
    
    TMenuItem* item3 = new TMenuItem(item2);
    item3->Caption = "menü 2";
    item3->OnClick = OnClick2;
    
    MainMenu1->Items->Add(item1);
    item1->Add(item2);
    item1->Add(item3);
    
    TMenuItem* item11 = new TMenuItem(MainMenu1);
    item11->Caption = "spez";
    
    TMenuItem* item12 = new TMenuItem(item1);
    item12->Caption = "menü 3";
    item12->OnClick = OnClick3;
    
    TMenuItem* item13 = new TMenuItem(item2);
    item13->Caption = "menü 4";
    item13->OnClick = OnClick4;
    
    MainMenu1->Items->Add(item11);
    item11->Add(item12);
    item11->Add(item13);
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::OnClick1(TObject *Sender)
    {
    Label1->Caption = "1";
    }
    void __fastcall TForm1::OnClick2(TObject *Sender)
    {
    Label1->Caption = "2";
    }
    void __fastcall TForm1::OnClick3(TObject *Sender)
    {
    Label1->Caption = "3";
    }
    void __fastcall TForm1::OnClick4(TObject *Sender)
    {
    Label1->Caption = "4";
    }
    //---------------------------------------------------------------------------
    

    Danke an alle die mir geholfen haben.

    Gruss Thomas



  • An das Löschen der Items (spätestens) zu Programmende hast du gedacht? 😉



  • Hallo

    @ kpeter : Manuelles Löschen ist nicht nötig, da den MenuItems immer ein Owner mit übergeben wurde. Der Owner ist für das Löschen zuständig.

    @Tim06TR : Noch nicht... aber vielleicht gibt es ja eine Forumsplugin, um Vorlagen für Antworten zu definieren? 😉

    bis bald
    akari



  • Zum Beenden des Programm.

    void __fastcall TForm1::OnClick2(TObject *Sender)
    {
    delete MainMenu1;
    Application->Terminate();
    }
    

    Ich denk mal, ich lösche das Menü, gebe so den Speicher frei, und Beende das Programm.
    Ist das gut?, bin ich ja mal gespannt. 🙄



  • Wenn ich das richtig sehe reicht:

    Application->Terminate();

    Gruss Thomas



  • Hallo

    Wenn du MainMenu1 nicht selbst mit new erstellst, dann solltest du es auch nicht manuzell löschen.
    Terminate ist in Ordnung.

    bis bald
    akari



  • akari schrieb:

    Hallo

    @ kpeter : Manuelles Löschen ist nicht nötig, da den MenuItems immer ein Owner mit übergeben wurde. Der Owner ist für das Löschen zuständig.

    Das ist wohl wahr.
    Allerdings setzt der Owner unseren Zeiger auf den Speicherbereich nicht auf NULL.
    Das mag zum Programmende relativ egal sein, kann aber innerhalb des Progs beim unbeabsichtigten Versuch, auf diesen Zeiger zuzugreifen, schiefgehen....

    mfg
    kpeter


Log in to reply