Nachrichten zwischen CLX-Frames versenden



  • Hallo,

    ich möchte Nachrichten an verschiedene CLX-TFrame versenden.

    Das bedeutet eigentlich, dass ich nur von irgendwo in meinem Programme eine Methode des CLX aufrufen möchte.

    Leider scheint die CLX-Signal-Implementierung in Borland C++ Builder 6 ziemlich fehlerhaft zu sein, wobei das Entwicklerhandbuch noch schlimmer ist.



  • markus.r schrieb:

    CLX-Signal-Implementierung

    Was genau meinst du damit?



  • Ich möchte Nachrichten an CLX-TFrames versenden, das bedeutet:

    Jedes Fensterprogramm entfängt im Prinzip Nachrichten vom Fenstersystem, wenn z.B. die Maustaste gedrückt wurde usw.

    Ich möchte nun eigene Nachrichten versenden und empfangen um damit das Entwurfsmuster "Controller-View-Model" abzubilden.



  • Ohne genau verstanden zu haben, worauf du hinaus willst: wie kommst du zu dem Eindruck, dass die "CLX-Signal-Implementierung" fehlerhaft wäre?
    Was hast du denn konkret probiert?



  • Exakt habe ich probiert nach "Borland C++ Builder 6 Entwicklerhandbuch Band II" Kapitel 51 vorzugehen:

    Dort ist das generieren von benutzerdefinierten "Qt-Ereignissen" so beschrieben:

    //Konstante fuer das neue Signal vereinbaren
    static const QEventType MyEvent_ID =(int) QCLXEventType_ClxUser + 50;
    
    //Event herstellen
    QCustomEventH* MyEvent= QCustomEvent_create(MyEvent_ID, this);
    
    //Event abschicken
    QApplication_postEvent(Application->Handle, MyEvent);
    

    und so lautet die korrigierte Version

    //Konstante fuer das neue Signal vereinbaren
    static const QEventType MyEvent_ID =(int) QEventType_ClxUser + 50;
    
    //Event erstellen und Abschicken
    QApplication_sendEvent( Application->Handle,
                      QCustomEvent_create(MyEvent_ID, this));
    

    Jedoch erzeugt der korrekte Code nun einen Stack-Overflow, da die Qt.hpp fehlerhaft ist.
    http://bdn.borland.com/article/0,1410,29631,00.html
    und hier ist die korrigierte Version:
    http://codecentral.borland.com/codecentral/ccWeb.exe/listing?id=19514

    Danach funktioniert das sogar.

    Ich habe dann versucht mit der Methode ::HookEvents(void) eine Signalbehandlungsroutine zu installieren und auf die Signale zu reagieren.
    Hier bietet das Handbuch nur sehr fehlerhaften Mischcode aus C++ und Object-Pascal, der prosaische Text klingt wie unverstanden übersetzt und hilft nicht weiter.

    Dabei sehe ich gerade:
    Kann ich die Methode ::EventFilter(..) vielleicht überschreiben.
    Wenn ich dort die Basisklassen-Version von EventFilter aufrufe, sollten die Standard-Events doch dann wie vorher verarbeitet werden?



  • Durch Beantwortung der Frage bin ich auf eine Teillösung gestoßen:

    Mein TFrame2 abgeleitet von TFrame sollte doch die Nachricht auffangen und bearbeiten.
    Wenn ich die Methode ::EventFilter(..) überschreibe, kann ich auf die Nachricht zumindest antworten, auch wenn der EventFilter eigentlich nicht dazu gedacht ist.

    bool __fastcall TFrame2::EventFilter(Qt::QObjectH* Sender, Qt::QEventH* Event)
    {
      //Methoden der Basisklasse nutzen
      bool retval = TFrame::EventFilter(Sender, Event);
      //eigener Behandlungscode
      switch (QEvent_type(Event))
        {
        case MyEvent_ID: reagiere_auf_die_nachricht();
        }//switch
    
      //Basisklassenmethodenergebnisse zurueckgeben
      return retval;
    }//EventFilter
    

    Jetzt sind nur noch zwei Probleme vor der Brust:

    1. Wie uebergebe ich Parameter dem Event, wahrscheinlich ist das aber der 2. Parameter von QCustomEvent_create(MyEvent_ID, this). Leider ist das alles undokumentiert und lieblos.
    2. Wie versende ich ein Signal Applikationsweit?
    Denn man muss die Nachricht explizit an ein Fenster wie folgt senden:

    //Event erstellen und Abschicken
    QApplication_sendEvent( this->MeinkleinesFrame->Handle,
                      QCustomEvent_create(MyEvent_ID, this));
    


  • Hallo,

    wenn man Nachrichten in CLX/Qt an alle Fenster verteilen will, dann ist das wie folgt möglich:

    void TForm1::broadcast(TWidgetControl* p_twidgetc, QCustomEventH* p_event)
    {
    //Broadcast via rekursivem Abstieg
    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);
        }
      }
    }//broadcast
    

    Das wird dann z.B. so aufgerufen:

    broadcast(static_cast<TWidgetControl*>(this),
                QCustomEvent_create(MyEvent_ID, this));
    

    Vielleicht kann man den ganzen Thread mal in Form einer Anleitung hier der Nachwelt zur Verfügung stellen, da das leider weder von Borland noch sonst wo im Internet dokumentiert ist.

    Gruss
    Markus


Anmelden zum Antworten