Serialisierungsprobleme



  • Hi,

    ich habe größere Probleme mit der Serialisierung bestimmter Daten meiner Dokumentenklasse und bräuchte dringend ein wenig Hilfe bzw. Anregungen.

    Ich versuche zunächst einmal meine Anwendung ein wenig zu erläutern:

    Es handelt sich um eine SDI-Anwendung, die vom User zu Beginn einige Eingaben verlangt. Diese Eingaben beeinflussen unter anderem das Aussehen eines Dialogs (Größe, Anzahl und Position verschiedener Steuerelemente, etc.), der zur Laufzeit dynamisch erzeugt wird und vom User anschließend aufgerufen werden kann.

    Ich möchte erreichen, dass der Dialog bei jedem Aufruf (auch nach dem Speichern und Öffnen des Dokuments) sein zur Laufzeit definiertes Aussehen behält und sich die zuletzt vorgenommenen Eingaben "merkt".

    Ich habe deshalb meine Dokumentenklasse mit Zeigern auf Instanzen dieser Dialogklasse ausgetattet (es existieren mehrere Instanzen). Um diese Daten speichern zu können, wollte ich die Dialogklasse selbst serialisierbar machen und ihre Serialize-Methode innerhalb der Serialize-Methode der Dokumentenklasse aufrufen.

    Ich habe dabei versucht, mich an die MSDN-Erläuterungen zu halten, bin dabei aber auf ein paar Fragen bzw. Probleme gestoßen.

    1.)
    Dort heißt es, es wird ein Konstruktor benötigt, der keine Argumente nimmt, um die Objekte beim Laden wieder erstellen zu können.
    Der Konstruktor meiner Klasse nimmt normalerweise ein int, das über die Anzahl der im Dialog enthaltenen Steuerelemente entscheidet. Im Konstruktor-Rumpf generiere ich mir die entsprechenden Elemente dann dynamisch und fülle damit einen Container.

    CMyClass::CMyClass(int Anzahl /*,...*/)
    : m_nAnzahl(Anzahl)
    {
        for (int i = 0, i < m_nAnzahl, i++)
        {
            //...
            CEdit tempEdit = new CEdit;
            //...
        }
    }
    

    Muss ich dies auch in dem geforderten Konstruktor ohne Argumente durchführen? Und wenn ja, wie mache ich die Anzahl der benötigten Steuerelemente dort bekannt, nachdem ich das int nicht übergeben darf?

    2.)
    Wann wird denn dieser Konstruktor im Rahmen der Serialisierung aufgerufen? Doch wahrscheinlich, bevor die Membervariablen der Klasse mit den serialisierten Werten gefüllt werden, oder? Wenn ich das m_nAnzahl-Member also serialisiere, kann ich es beim Laden im ctor-Rumpf noch nicht als Schleifenvariable benutzen, oder?

    Wäre toll, wenn ihr ein paar Anregungen für mich hättet. Auch für Links, unter denen ich ein wenig detailliertere Informationen zur MFC-Serialisierung finden könnte, wäre ich dankbar. Alles, was ich bisher gefunden habe, bezog sich entweder nicht auf die MFC (CObject::Serialize()) oder war wenig ausführlich.

    Danke im Voraus!



  • Also wenn ich Dich richtig verstanden habe dann willst Du von der Doc-Klasse heraus über Zeiger auf die Dialog-Instanzen zugreifen. Wäre es nicht sinnvoller die Daten in der Doc-Klasse zu halten und dem Dialog im Ctor einen Zeiger auf das Doc mitzugeben? Dann kann der Dialog auf das Doc zugreifen und die Serialisierungsmechanismen des Doc würden dann die Speicherung sozusagen zentral übernehmen. Musst nur schauen das die Du vor dem Zugriff die Daten validierst wenn mehrere Instanzen des Dialoges existieren.


  • Mod

    Ich sehe das genauso, wie AndyDD!

    Du soltest die Daten über den View in das Doc angelegen. Das Doc sollte nicht abhängig von dem View sein und dessen Design nicht kennen. Du benötigst nur einen entsprechenden Mechanismus der über UpdateAllViews die Daten anholt, d.h. der View speichert die Daten im Doc!



  • Danke für die Anregungen!

    Ihr habt natürlich eigentlich vollkommen Recht. Ich dachte, wenn ich ohnehin die Daten, die der User im Dialog modifiziert im Dokument brauche, kann ich eigentlich gleich Dialogpointer als Member der Dokumentenklasse verwenden und habe damit sämtliche Informationen, die der Dialog enthält, erschlagen. Damit habe ich mir offensichtlich selbst ein Ei gelegt 🤡

    Ich werde also wahrscheinlich die DDX-Variablen der Dialogklasse (bzw. deren Werte) in die Dokumentenklasse übernehmen, damit sollte ich dann die Serialisierung hinbekommen.

    Obwohl mir adhoc kein vernünftiges Beispiel einfällt, verbleiben trotzdem noch ein paar Fragezeichen. Meine Dokumentenklasse könnte doch Member einer bestimmten Klasse haben, die keine Dialogklasse ist. Um diese Objekte zu serialisieren, würde ich doch auch den Weg gehen, dass ich die entsprechende Klasse serialisierbar mache und deren Serialize-Methode in der Serialize-Methode meiner Dokumentenklasse aufrufe, oder? Und dann könnte ich mir vorstellen, dass ich erneut auf Probleme stoße, wie ich sie oben beschrieben habe...

    Falls mich dazu jemand noch ein wenig aufklären kann, wäre ich dankbar. Meinen konkreten Fall sollte ich mit den bisherigen Antworten allerdings lösen können.


  • Mod

    Es gibt keinen spezifischen Weg wie man Dialog und Docs verbindet. Das hängt einfach auch von der Anwendung ab.

    Ich mache es meistens so:
    1. normale DDX_ Routinen im CFormView
    2. Wenn die Daten im Document benötigt werden rufe uch UpdateAllViews mit einem bestimmten Hint (Save/Commit) Wert auf (Siehe Parameter dieser Funktion).
    3. Wenn neue Daten aus dem Document geladen werden mache ich es genauso. Ich rufe UpdateAllView mit einem entsprechenden Hint (Load/Set) auf.

    Mit dieser Methode kann man auch komplexere Elemente in einem Doc/View System behandeln bei denen die Daten irgendwie doch erstmal in ein Control geladen werden und letzten Endes "doppelt" gehalten werden oder zumindest als Kopie.

    HTH


Anmelden zum Antworten