Nicht erklärbarer Fehler mit Frames (Anwendung reagiert nicht mehr auf Mausklicks)



  • Hallo,

    ich hab ein merkwürdiges Problem. Ich arbeite an einem etwas größeren Projekt.
    Es ist im Laufe der Zeit immer mehr angewachsen. Und so musste ich mir Möglichkeiten überlegen den Überblick nicht zuverlieren.

    Die Anwendung besteht aus einem Hauptformular und mehreren Frames die jeweils eine unterschiedliche Unteransicht bereitstellen. Am Anfang hab ich die Frames noch alle zur Entwurfszeit auf dem Formular plaziert und je nach bedarf ein und ausgeblendet. Auch das wurde unübersichtlich.

    Also bin ich hergegangen und habe mir eine Framemanager geschrieben der die Frames zur Laufzeit verwaltet und intern ein std::set von einem std::pair von Framezeigern und einem enum der die jeweiligen Ansichten durchnummeriert enthält.
    Der Framemanager selbst ist Member eines Datenmodules welches für die Erzeugung der Frames zur Laufzeit verantwortlich ist.
    Jeder Frame wird zusätzlich von einer abstracten Basisklasse ManagableFrame abgeleitet. Sodass sie die Methoden Prepare(),Cleanup(),Appeare() und Disappeare() implementieren müssen.

    Der Framemanager hat als interface 3 einfache Funktionen:
    InsertFrame() //fügt einen Frame hinzu
    DispatchFrame() //Wechselt die Ansicht in Abhängigkeit vom parameter
    SelectFrame() //liefert eine Zeiger auf einen bestimmten Frame zurück

    Nun zu meinem Problem. Als Behandlungsroutine für ein Click-Ereignis werden die Frames gewechselt. Dazu wird die DispatchFrame() Funktion des Framemanagers verwendet.
    Diese sucht den richtigen Frame zum enum und ruft Prepare() und danach Appeare() auf. Wenn bereits ein Frame gezeigt wird werden vorher dessen Cleanup() und Disapeare() Methoden aufgerufen.

    Die Appeare-Methode der einzelnen Frames ist i.d.R. nur ein einfaches Visible=true und manchmal wird noch ein Focus gesetzt.

    Nun ist es so dass das bei einigen Frames funktioniert und bei anderen nicht. Einige werden correct angezeigt, andere werden nicht angezeigt aber die Anwendung läuft normal weiter. Und wieder andere werden nicht angezeigt und die Anwendung reagiert nicht mehr auf Clicks. Sie behandelt weiter mousemove und mousleave Ereignisse.

    Das Problem dass sich mir stellt ist dass für die verschiedenen Frames die selben Methoden in der selben Reihenfolge aufgerufen werden (die von der Basisklasse geerbten) aber eben unterschiedliche Ergebnisse auftreten.

    Vielleicht hilft etwas code:
    Es ist schwierig ein Minimalbeispiel zu geben..

    Aber ich hab die Vermutung dass es an der Erzeugung der Frames liegt auch wenn die ja wieder identisch für alle Frames ist.
    Beim Durchlaufen mit dem Debugger konnte ich sehen, dass der Manager den richtigen Frame findet bzw. einen Zeiger auf diesen und auch dessen Prepare bzw. Appeare Methode aufgerufen wird. Nur einige Frames sind nach Visible=true wirklich sichtbar und die andren nicht bzw. das merkwürdige Verhalten zeigt sich.

    //modFrame.cpp
    const bool TmodFrame::CreateFrames(void){
          Application->CreateForm(__classid(TFrame1), &fr1_);
          Application->CreateForm(__classid(TFrame2), &fr2_);
          Application->CreateForm(__classid(TFrame3), &fr3_);
    
          //hier werden die Framzeiger in den Manager eingefügt
          //ftFR1 usw. sind enums
          fmanager_.Insert(fr1_,ftFR1);
          fmanager_.Insert(fr2_,ftFR2);
          fmanager_.Insert(fr3_,ftFR3);
    
          fr1_->Visible=false;
          fr2_->Visible=false;
          fr3_->Visible=false;
    
          MainForm->InsertControl(fr1_);
          MainForm->InsertControl(fr2_);
          MainForm->InsertControl(fr3_);
    
         //.......
         return true;
    }
    

    Wenn jemand eine Vermutung hat oder sogar weiss warum das so merkwürdig ist, ich bin für jede Hilfe dankbar.

    Sofar....



  • Ich antworte mir mal selbst. Ich hab heute morgen nochmal rumprobiert und es scheint wirklich an der Art zu liegen wie ich die Forms erstelle.
    Mit TForm::InsertControl() scheint es nicht zu gehen nach vorherigem TApplication::CreateForm(). Jedenfalls nicht zuverlässig.

    Wenn ich die Frames mit new erzeuge und als owner das Hauptformular angebe und anschliessen die Parenteigenschaft des Frames auf das Hauptformular lege funktioniert es wie erwartet.

    Ich bin froh dass es nun geht, wäre aber froh wenn mir vielleicht jemand erklären könnte warum es so wie ich es Anfangs probiert habe nicht geht.

    Sofar....



  • Wenn Du einen eigenen Framemanager verwendest, sollte dieser auch die nicht mehr benötigten Instanzen löschen, nicht die Application oder ein Form...



  • Das ist ja richtig, das Problem dass sich aber dann stellt ist, dass die Frames erst garnicht angezeigt werden. Gebe ich kein Parent und keinen Owner sieht man nichts von den Frames. Mit dem freigeben das MainForm zubeauftragen ist in diesem Fall aber kein Problem da die Frames nur einmal erzeugt werden und während der ganzen Zeit erhalten bleiben sollen, jedenfalls solange wie auch das MainForm existiert. Wenn es nicht mehr existiert bedeutet das auch dass die Anwendung beendet ist. Das ist durchaus was ich will. Ich möchte die Frames nicht immer nur erzeugen wenn Sie gebraucht werden.

    Der Sinn des Managers ist nur zwischen den Frames hin und her zuschalten und sie entsprechend vorzubereiten. Es ist keine Framefactory.

    Das was sich nun vereinfacht hat ist dass ich mir sicher sein kann dass die Frames für ihre verwendung vorbereitet sind und dass ich sie über ihre enummerationen auswählen kann.

    Sofar ...


Anmelden zum Antworten