Zuverlässigkeit des TMenuItem::Command Wertes



  • Hallo,
    ich möchte einige MenuItems anhand irgendeinen Wertes eindeutig identifizieren können. Dazu gibt es soweit ich weiß verschiedene Möglichkeiten.
    1. Über die Speicheradresse. Ist aber schlecht, da man daran nicht zuverlässig erkennen kann ob ein Objekt (in meinem Fall TMenuItem) existiert.
    2. TComponent:Tag ist schlecht, weil es von außerhalb geändert werden kann.
    3. Die einzige gescheite Lösung scheint für mich TMenuItem::Command zu sein, da es
    von außerhalb nicht geändert werden kann.
    Aber ich weiß nicht so richtig ob es auch im ganzen Programm eindeutig ist. Und ob sich ihr Wert für die Laufzeitdauer eines Programms nicht geändert wird, sonst werden falsche oder gar kein Menü gefunden. Weiß jemand, ob diese Command-ID irgendwie geändert werden kann und auch geändert wird (z.B. durch VCL). Wenn ja, gibt es bessere Möglichkeiten, Menus eindeutig zu identifizieren, ohne neue Komponenten erstellen bzw. von alten ableiten zu müssen.



  • Hallo,

    schon gelesen was die Hilfe zu Command sagt:

    CBuilder-Hilfe schrieb:

    Die Eigenschaft Command legt die dem Menüeintrag zugeordnete Befehls-ID von Windows fest.

    __property Word Command = {read=FCommand, nodefault};

    Beschreibung

    Verwenden Sie Command in Anwendungen, die WM_COMMAND-Botschaften direkt verarbeiten. Wenn der Benutzer einen Menüeintrag auswählt, sendet Windows eine WM_COMMAND-Botschaft an das Fenster, das mit dem Eintrag verbunden ist. In ItemID der Botschaft ist den Wert der Eigenschaft Command des ausgewählten Menüeintrags enthalten.

    Ich glaube kaum, dass diese zur Laufzeit ihren Wert verändert. Dass würde sonst irgendwie das Prinzip von Windows durcheinander bringen. Wenn du eine reine WinApi-Anwendung ohne VCL schreibst, brauchst du für deine Controls ja auch eine ID, damit du in der WndProc für WM_COMMAND abfragen kannst, von welchem Control es ausgelöst wurde.

    MfG
    tuküe



  • Sicher habe ich in der Hilfe gelesen. Aber da steht es nicht explizit, dass es intern von der VCL (nicht) geändert wird.

    tuküe schrieb:

    Ich glaube kaum, dass diese zur Laufzeit ihren Wert verändert

    Dasselbe glaube ich zwar auch, aber wissen tue ich es nicht. Damit ich später nicht von irgendwelchen wundersamen Bugs "verfolgt" werde, habe ich hier die Frage auch gestellt.
    Das ganze Programm (bis auf ein Fenster) verwendet VCL, deswegen werden auch die WM_COMMAND Nachrichten von der VCL intern verwaltet, und wieso sollte sie dann auch die menuID nicht ändern können?



  • wieso nimst du nicht den Namen. 🙄



  • Hallo,

    @bIce
    Ich glaube die VCL wäre in diesem Punkt schlecht konzipiert, wenn es so wäre. Es würde für mich keinen Sinn ergeben.

    @AndreasW
    Ich glaube deswegen nicht:

    bIce schrieb:

    1. Über die Speicheradresse. Ist aber schlecht, da man daran nicht zuverlässig erkennen kann ob ein Objekt (in meinem Fall TMenuItem) existiert.

    In der VCL sind ja alle Objekte Zeiger.
    Ich würde aber auch einfach den Namen nehmen.

    MfG
    tuküe



  • tut mir leid, ich seh da kein Problem. Wenn du ein Objekt hast hast du ein Objekt, und das hat einen Namen. Es gibt kein Problem.



  • AndreasW, meins Du mit Namen der Variablen? Dann geht es nicht, die Objekte werden dynamisch erstellt. Und ich muss sie irgendwie in einer Liste verwalten. Wenn Du aber den im Objektinspektor zugewiesenen Wert für TComponent::Name meinst, dann habe ich daran nicht gedacht, sollte aber theoretisch funktionierten, wenn ich eine Factory-Klasse erstelle, die eine Komponente mit eindeutigen Namen erstellt, oder?



  • bIce schrieb:

    wenn ich eine Factory-Klasse erstelle, die eine Komponente mit eindeutigen Namen erstellt, oder?

    wieso, das geschiet ja automatisch oder nicht. Es wird ja automatisch die Nummer, welche am Namen angehängt wird hochgezählt. ICh glaub das passiert in TCOmponent über einen statischen Counter. Der Name üsste also eindeutig sein. Du kannst ihn natürlcih aber auch selber setzen und eindeutig machen.



  • AndreasW schrieb:

    wieso, das geschiet ja automatisch oder nicht.

    Leider nicht, wenn man die Komponente zur Laufzeit erstellt.

    void __fastcall TForm1::Button1Click(TObject* Sender)
    {
       TButton* btn = new TButton(this);
       btn->Left = 10;
       btn->Top = 10;
       btn->Caption = "Hallo";
       btn->Parent = this;
       ShowMessage(btn->Name); // wird nur die leere MessageBox angezeigt
    }
    


  • oh, sorry.

    hm, das Handle sollte aber eindeutig sein.


Anmelden zum Antworten