Neuer Menüeintrag erstellt, aber wie aktion auslösen?



  • Hallo,

    ich habe in meinem Programm eine Funktion das Namen aus einer Datei liest, nun möchte ich die namen in meinem MainMenu einfügen, was auch klappt.

    for(it_s = server_list.begin(); it_s != server_list.end(); ++it_s)
        {   TMenuItem* addItem = new TMenuItem(Menu);
            server_tmp = *it_s;
            tmp = server_tmp.name;
            addItem->Caption = tmp.c_str();
            Menu->Items->Items[0]->Add(addItem);
        }
    

    Aber ich kann ja leider nicht im Programmcode eine Funktion aufrufen die es noch nicht gibt...

    void __fastcall TFormMain::Neu1Click(TObject *Sender)
    {
    
    }
    

    z.B.

    Kann mir da einer weiterhelfen? ich habe hier mit der Suche gelesen das man da Tag von MainMenu bentzen kann... aber ich kann mir in keinster weise vorstellen wie!? 😞

    wäre super wenn mir da einer helfen könnte.

    Gruß
    Gustl



  • Hi,

    ich hab mir dann immer ausgeholfen, indem ich solch ein MenuItem per Hand (also nicht zur Laufzeit) erstellt hab, um dann davon eine OnClick-Methode zu erstellen und diese in der cpp und im Header umzuschreiben. Da kannste dir dann sicher sein, dass du keine Fehler bei der Syntax gemacht hast.

    Grüße
    Christian



  • Hallo,

    ja, das würde gehen wenn ich zuvor weiß welche Einträge ich im Menu benötige, aber das soll ja alles während der Laufzeit passieren.

    Trotdem danke.



  • Ach, jetzt weiß ich, wie dus meinst. Erstelle doch einfach nur eine OnClick-Methode für alle Einträge, dann fange den Sender ab (welcher Eintrag geklickt wurde, notfalls auch mit der Caption des Items) und dann benutze diese Informationen, um dein Ereignis je nach Eintrag unterschiedliche Dinge machen zu lassen.

    //Edit: Schau mal hier: http://www.c-plusplus.net/forum/viewtopic-var-t-is-250401



  • Danke.

    Ich finde leider kein OnClick für die einzelnen untermenüs... bzw. für alle..
    Mein Menü heißt Server, und dort sollen alle servernamen, die von der datei ausgelsen wurden, anklickbar sein...

    server gibt ein OnClick, aber löst bei den erzeugenten namen nicht aus...

    #include <vector>
    #include <utility>
    
    typedef std::pair<TCheckBox*, TEdit*> Pair_t;
    typedef std::vector<Pair_t>           PairVector_t;
    
    class TForm1 : public TForm
    {
       ...
       PairVector_t  Paired_;
       ...
    };
    
    __fastcall TForm1::TForm( TObject* Owner )
    {
       for( int i = 0; i < 7; ++i )
       {
          // Komponenten erzeugen
          TEdit* pEdit = new TEdit( this );
          TCheckbox* pCheckbox = new TCheckBox( this );
    
          pCheckBox->OnClick = OnClickMyCheckBox;
    
          // paarweise in Vektor einfügen
          Paired_.push_back( std::make_pair( pCheckBox, pEdit ) );
       }
    }
    
    void __fastcall OnClickMyCheckBox( TObject* Sender )
    {
       TCheckBox* pChk = dynamic_cast<TCheckBox*>( Sender );
       if( NULL != pChk )
       {
          // quick´n´n dirty, ein Function object und std::find wären schöner
          for( PairVector_t::iterator it = Paired_.begin(); it != Paired_.end(); ++it )
          {
             if( it->first == pChk )
             {
                TEdit* pEdit = it->second;
                // mach was pEdit
             }
          }
       }
    }
    

    könnte mir das vielleicht einer so abändern das es für mich passt? und eventuell ein wenig erklären?

    wäre sehr nice.

    Gruß
    Gustl



  • Kenn mich mit vektoren ehrlich gesagt nicht aus, hier meine simple Lösung:

    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    	int TopPos = 0, Nr=0;
    
    	for(int i=0;i<=2;i++) //erstellt 3 Buttons
    	{
    	   TButton* MeinButton = new TButton(Form1);
    	   MeinButton->Parent = Form1;
    	   MeinButton->OnClick = MeinButtonClick;
    	   MeinButton->Caption = Nr; //nummeriert die Buttons per Caption
    
    	   MeinButton->Top = 50 + TopPos;  //platziert die Buttons untereinander
    	   TopPos += 50;
    
    	   Nr++;
    	}
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::MeinButtonClick(TObject *Sender)
    {
       TButton* CheckButton = dynamic_cast<TButton*>( Sender );
       if( NULL != CheckButton )
       {
    	   ShowMessage("Button Nummer " + CheckButton->Caption + " wurde geklickt!");
       }
    }
    

    Header:

    class TForm1 : public TForm
    {
    __published:	// IDE-managed Components
    	TButton *Button1;
    	void __fastcall MeinButtonClick(TObject *Sender);
    	void __fastcall Button1Click(TObject *Sender);
    private:	// User declarations
    public:		// User declarations
    	__fastcall TForm1(TComponent* Owner);
    };
    

    Hoffe, das hilft/reicht dir.

    Grüße



  • Hallo,

    ich bin mir nicht ganz sicher Dich richtig verstanden zu haben, habe auch auch jetzt nicht die große Lust mich durch Deinen Code zu arbeiten 🕶
    Ich gebe Dir jetzt mal ein Beispiel wie Du einfach per Button ein Menü erzeugst und anschließend auch an die clicks kommst:

    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    
           TMenuItem *Menu   = new TMenuItem(MainMenu);
           MainMenu->Items->Insert(0, Menu);
           Menu->Caption     = "Datei";
    
           TMenuItem *Entry[10];
           for (int i=0;i<10;i++)
             {
              Entry[i]  = new TMenuItem(Menu);
              Entry[i]->Caption    = "Eintrag_"+IntToStr(i);
              Entry[i]->OnClick = Action1Execute;
              Menu->Insert(i, Entry[i]);
             }
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::Action1Execute(TObject *Sender)
    {
      ShowMessage(dynamic_cast <TMenuItem*>(Sender) -> Caption + " angeklickt." );
    }
    

    Ich hoffe das hilft Dir schon mal weiter.

    Gruß myerscola



  • Danke euch beiden, jetzt funktioniert es... fast

    Noch ein kleines Problem, wenn ich Caption jetzt in einer if abfrage vergleiche stimmen diese nicht überein...

    if(dynamic_cast <TMenuItem*>(Sender) -> Caption == String)
    

    wenn ich caption mit ShowMessage ausgebe, ist der erste Buchstabe auch unterstrichen... warum das?

    Edit:
    Ich habe das dann mit Tag realisiert.

    Danke nochmal.



  • Habe es mir nochmal angesehen und bin da auch überfragt.
    Nur lege doch einfach in deiner Schleife den Itemnamen fest mit:

    Entry[i]->Name =  "ItemName_"+IntToStr(i);
    

    Dann caste den in Deiner Abfrage:

    if(dynamic_cast <TMenuItem*>(Sender) -> Name == String)
    

    Das habe ich eben auch nochmal getestet, das geht in jedem Fall.
    Woher diese Unterstriche kommen kann ich mir nicht erklären, vielleicht hat aber jemand der Anderen hier eine Idee.

    Gruß myerscola



  • das dort Buchstaben unterstrichen sind liegt wahrscheinlich an der Eigenschaft AutoHotkeys, diese setzt für jeden Menüeintrag automatisch ein eindeutiges Kürzel, damit man halt auch über die Tastatur auf die Einträge zugreifen kann, dann erscheint dieses Hotkey als unterstrichener Buchstabe und in der Caption wird automatisch ein & vor dem betroffenen Buchstaben gesetzt


Anmelden zum Antworten