MDI - Childfunktionalität ansprechen



  • Hallo Zusammen,

    ich habe eine MDI-App geschrieben, und möchte ein ListView ansprechen, doch leider liegen die methoden deklarationen im Private Bereich (so vermute ich) und sind vom Hauptfenster (MDI) wohl tabu, oder irre ich mich.

    kann man über ActiveMDIChild irgendwelche kompos auf dem Child ansprechen?

    falls ja, wie? 🙂

    Danke Gruß Gerd



  • Komponenten in einem Formular werden unter published angelegt. Einfach mal die Headerdatei ansehen.

    Die Sichtbarkeitsregeln für Elemente, die als published deklariert sind, sind identisch mit denjenigen für Elemente, die als public deklariert sind. Der einzige Unterschied liegt darin, daß die Laufzeit-Typinformation im Stil von Object Pascal (RTTI) nur für Datenelemente und Eigenschaften generiert wird, die in einem __published-Abschnitt stehen. Die RTTI ermöglicht es einer Anwendung, die Datenelemente, Elementfunktionen und Eigenschaften eines andernfalls unbekannten Klassentyps abzufragen.



  • Hallo

    ActiveMDIChild gibt TForm zurück, also kannst du das übliche über TForm::FindComponent() oder TForm::Component[] mit einem cast machen. Siehe auch FAQ Abschnitt Komponenten dazu.

    bis bald
    akari



  • ok, aber wie spreche ich Sie an?

    zum Beispiel wie gebe ich einen Button auf einem Child über das MDI eine neue Caption?

    gruß gerd



  • Hallo

    oder noch besser : gleich auf das MDI-Form casten.

    // Aus einer Methode des Hauptforms heraus
    TMyMDIForm *CurChild = static_cast<TMyMDIForm *> (ActiveMDIChild);
    CurChild->Edit->Text = "x";
    

    bis bald
    akari



  • Danke für eure Hilfe, funkt wunderbar. war aber zu 90% schon auf dem richtigen Wege! 🙂

    gruß gerd



  • ohne nun verwirren zu wollen:

    Ich habe ein aehnliches Problem bei einer Controller-View-Model-Implementierung gehabt, dass ich bei den unterschiedlichen Views keine zugreifbaren Methoden anbauen konnte.

    Ich habe mir mit Fensternachrichten geholfen, welche jeder View empfaengt und dann in die passende Behandlungsroutine verzweigt.
    Die Loesung ist fuer CLX, aber leicht auf VCL uebertragbar (, da im Gegensatz zu dem CLX-Message-System die VCL-Version vollstaendig und vor allem richtig dokumentiert ist).

    //Die Qt-Message
    static const QEventType Event_aenderung_ID =(int) QEventType_ClxUser + 50;
    
    //diese Nachricht in einem View empfangen
    bool __fastcall TFrameXXX::EventFilter(Qt::QObjectH* Sender, Qt::QEventH* Event)
    {
      //Methoden der Basisklasse nutzen
      bool retval = TFrame::EventFilter(Sender, Event);
      //eigener Behandlungscode
      switch (QEvent_type(Event))
        {
        //verzweigen zu meiner Behandlungsroutine
        case ControllerViMo::Event_aenderung_ID /*2050*/: this->event_aenderung();
        }//switch
      //Basisklassenmethodenergebnisse zurueckgeben
      return retval;
    }//EventFilter
    
    void TFrameXXX::event_aenderung(void)
    {
      //tu was
    }
    

    Die Nachrichten werden über folgenden zentralen Broadcastmechanismus an jeden View bzw. alle Fensterelemente verteilt (der im Controller eingebaut ist):

    void ControllerViMo::broadcast(TWidgetControl* p_twidgetc, QCustomEventH* p_event)
    {//Broadcast via rekursivem Abstieg
    if (this->p_hauptfenster != NULL)
     {
     for (int i= 0; i < p_twidgetc->ComponentCount; ++i)
      {//ueber alle direkten Komponenten
      if (TWidgetControl* twc= dynamic_cast<TWidgetControl*>(p_twidgetc->Components[i]))
        {
        QApplication_sendEvent(twc->Handle, p_event);
        //Absteigen
        broadcast(twc, p_event);
        }//war es ein TWidgetControl?
      }//ueber alle Componenten
     }//if p_hauptfesnter valid
    }//broadcast
    

    Die Lösung ist zwar etwas kompliziert, aber auf diese Weise umgeht man den static_cast. Man umgeht damit das Problem, dass man den Typ des empfangenden Fensters sicher feststellen muss.
    Wenn man aus Versehen an falschen Fensterelementtyp die Nachricht verschickt, dann macht das nichts, denn die reagieren einfach gar nicht darauf.

    Die Lösung funktioniert gut, ist sicher und auch performant, was den Mehraufwand rechtfertigt.

    Übrigens kann man auch dediziert senden anstatt des Broadcastes, indem man nur QApplication_sendEvent(...,p_event); aufruft.


Anmelden zum Antworten