Designfrage: Datenaustausch zwischen Optionsdialog und Programm
-
Welche Vorteile soll Dir das bringen? Ich würde dem Dialog eine Get- und eine Set-Methode verpassen und die dann mit den entsprechenden Members des Docs verbinden. Voraussetzung ist, dass der Konstruktor des Dialogs einen gültigen Zeiger aufs Doc mitbekommt. Die Getmethode braucht man für die Anzeige der bisherigen Einstellungen, die Set-Methode zum Schreiben in das Doc. Diese kann ja in der OnOk aufgerufen werden. Möglicherweise machst Du den gleichen Ansatz, nur schau ich auf den ersten Blick bei Deinem Konstrukt nicht ganz so durch.
Ja DD steht für Dresden, warum?
-
Stimmt der Getter fehlt noch im Bsp. einfach dazudenken

An Vorteilen sehe ich einige:
- das Interface an sich, man sieht halt gleich was geht,
- Verlagerung des relevanten Codes in den OptionsDlg,
- Wiederverwendbarkeit
- einfachste Überschreibung der Get und Set Methoden (ok, gilt nur für mich
)und noch einige andere die mir grad nicht einfallen

Achso, wegen DD, üsch wohn och hier

-
connan schrieb:
Stimmt der Getter fehlt noch im Bsp. einfach dazudenken

An Vorteilen sehe ich einige:
- das Interface an sich, man sieht halt gleich was geht,
- Verlagerung des relevanten Codes in den OptionsDlg,
- Wiederverwendbarkeit
- einfachste Überschreibung der Get und Set Methoden (ok, gilt nur für mich
)und noch einige andere die mir grad nicht einfallen

Achso, wegen DD, üsch wohn och hier

Na dann hallo Landsmann.
Du magst sicher Recht haben, aber ob das einfacher ist... Und wo ist der Bezug zum Doc der Anwendung, also dort wo man die Daten zur Laufzeit verwalten will?
Aber wenn wir hier schon über Design reden, da hab ich auch noch mal eine Frage. Ich habe ein Programm welches eine Maschine steuert. Für verschiedene Artikel sind die Einstellwerte in jeweils verschiedenen Ini-Dateien gespeichert. In der Registry hinterlege ich, welches Profil zuletzt verwendet wurde. Beim Programmstart wird dann die entsprechende Ini-Datei geladen und im Ctor des Docs werden die Variablem mit den Werten der Ini-Datei initialisiert.
Jetzt gibts da auch einen Optionsdialog, in dem ich die Werte editieren kann. Beim Beenden mit Ok müssen die Werte übernommen werden. Jetzt muss ich einerseits die Variablen im Doc ändern und andererseits die Ini neu schreiben. Was sollte man jetzt als zentrales Element ansehen. Die Ini-Datei oder das Doc der Anwendung? Oder ist die hier geschilderte Vorgehensweise generell ungünstig?
-
@connan: Und das Problem ist noch das gleiche wie vorher - ich muß immer noch von Hand jede Variable zwischen Hauptprogramm und Optionen-Dialog austauschen (und dadurch, daß dieser Austausch von der OnOption()-Methode des Hautpprogramms in die OnInitDialog()/OnOk() Methoden des Dialogs ausgelagert wird, verschlimmbessert sich (imho) die Situation eher.
(ich hab' ja nicht nur eine Variable, sondern ca. ein halbes Dutzend ;))
-
mach dir doch einen optionmanager, der global verfügbar ist. der hat dann zwei funktionen 'SetOption (option_id_or_name, option)' und 'GetOption (option_id_or_name)'.
erstere trägt options ein, sollte die option noch nicht existieren, wird sie neu angelegt, andernfalls der wert einer vorhandenen option überschrieben.
vorteil ist, dass der 'option-leser' nur den namen (oder die id) der option kennen muss. beim setzen/ändern in der dialog-handlerfunction musste immer nur die 'SetOption()' funktion aufrufen.
ausserdem lässt sich so ein objekt prima beim starten mit gespeicherten options (aus einem config-file o.ä.) füllen.

edit: such mal im internet (bei code project oder so)
das gibt's bestimmt schon fertig.
-
pale dog schrieb:
mach dir doch einen optionmanager, der global verfügbar ist. der hat dann zwei funktionen 'SetOption (option_id_or_name, option)' und 'GetOption (option_id_or_name)'.
erstere trägt options ein, sollte die option noch nicht existieren, wird sie neu angelegt, andernfalls der wert einer vorhandenen option überschrieben.
vorteil ist, dass der 'option-leser' nur den namen (oder die id) der option kennen muss. beim setzen/ändern in der dialog-handlerfunction musste immer nur die 'SetOption()' funktion aufrufen.Deswegen bleibt es trotzdem dabei, daß ich für jede jede Option, die ich benötige, zwei Membervariablen benötige (eine im Hauptprogramm und eine im Optionsdialog) und diese miteinander synchronisieren muß. Und alle bisherigen Lösungen laufen doch wieder darauf hinaus, daß eine Seite (mit deinem Ansatz sogar beide Seiten) manuell die Variablen synchron halten muß. Optimal wäre es, wenn ich die Variablen nur einmal hätte und von überall dort rankommen könnte.
Nachtrag: Nur eine Idee, die mir gerade gekommen ist:
Wenn ich den COptionDialog nicht lokal anlege, sondern in meine MainDlg-Klasse reinpacke, könnte ich eigentlich von überall an seine Member rankommen. Wäre so etwas praktisch umsetzbar?//noch nicht getestet void OnOption() { if(m_opt.DoModal()!=IDOK) { //*grübelt* Hier müsste ich die alten Werte zurückholen } } void OnSomething() { mach_was_mit(m_opt.m_var1); ... }
-
CStoll schrieb:
pale dog schrieb:
mach dir doch einen optionmanager, der global verfügbar ist. der hat dann zwei funktionen 'SetOption (option_id_or_name, option)' und 'GetOption (option_id_or_name)'.
erstere trägt options ein, sollte die option noch nicht existieren, wird sie neu angelegt, andernfalls der wert einer vorhandenen option überschrieben.
vorteil ist, dass der 'option-leser' nur den namen (oder die id) der option kennen muss. beim setzen/ändern in der dialog-handlerfunction musste immer nur die 'SetOption()' funktion aufrufen.Deswegen bleibt es trotzdem dabei, daß ich für jede jede Option, die ich benötige, zwei Membervariablen benötige (eine im Hauptprogramm und eine im Optionsdialog) und diese miteinander synchronisieren muß.
nein, der optionmanager verwaltet alles.
du musst bzw. darfst nur über die set/get-funktionen darauf zugreifen und brauchst keine kopien anzulegen. hauptprogramm und optionsdialog greifen beide auf die (nur einmal existierende) globale instanz des optionmanagers zu.

-
CStoll schrieb:
Nachtrag: Nur eine Idee, die mir gerade gekommen ist:
Wenn ich den COptionDialog nicht lokal anlege, sondern in meine MainDlg-Klasse reinpacke, könnte ich eigentlich von überall an seine Member rankommen. Wäre so etwas praktisch umsetzbar?//noch nicht getestet void OnOption() { if(m_opt.DoModal()!=IDOK) { //*grübelt* Hier müsste ich die alten Werte zurückholen } } void OnSomething() { mach_was_mit(m_opt.m_var1); ... }Ist sicherlich eine bessere Variante als die erste, aber da hast Du ja wieder public Member

Mir ist gerade noch was eingefallen, ich hab mal einen Artikel in der MSDN gefunden der beschrieb wie man seine eigenen DDX Methoden implementiert. Da man an die Standard DDX imho leider keine Referenzen übergeben kann müsste man sich seine eigenen DDX schreiben wo genau das geht.
Wenn Dir die public Memebr egal sind kannst du natürlich auch im Optionsdialog in OnDataExchange die DDX- Aufrufe auf die Variablen des MainDlg umleiten. Ist vieleicht das einfachste.
@pale dog:
Die globale Haltung aller Variablen ist zwar verlockend, macht doch aber die Vorteile der OOP wieder zunichte.
-
Hallo,
das Problem hatte ich auch.
Wenn du
COptionDlg opt;
nicht nur temporär in On... erzeugst, sondern diese Klasse
permanent in deinem Doc hältst, dann kannst du auch die Werte
der Klasse abfragen.Gruß Andreas
-
AndyDD schrieb:
... Und wo ist der Bezug zum Doc der Anwendung, also dort wo man die Daten zur Laufzeit verwalten will?
Bei doc/view erhält natürlich das doc das Interface.
AndyDD schrieb:
...
Aber wenn wir hier schon über Design reden, da hab ich auch noch mal eine Frage. Ich habe ein Programm welches eine Maschine steuert. Für verschiedene Artikel sind die Einstellwerte in jeweils verschiedenen Ini-Dateien gespeichert. In der Registry hinterlege ich, welches Profil zuletzt verwendet wurde. Beim Programmstart wird dann die entsprechende Ini-Datei geladen und im Ctor des Docs werden die Variablem mit den Werten der Ini-Datei initialisiert.
Jetzt gibts da auch einen Optionsdialog, in dem ich die Werte editieren kann. Beim Beenden mit Ok müssen die Werte übernommen werden. Jetzt muss ich einerseits die Variablen im Doc ändern und andererseits die Ini neu schreiben. Was sollte man jetzt als zentrales Element ansehen. Die Ini-Datei oder das Doc der Anwendung? Oder ist die hier geschilderte Vorgehensweise generell ungünstig?Klingt gut was Du da machst, ich würde auf jedenfall die doc als Zentrale nutzen, die Ini must du ja erst beim beenden neu schreiben oder?
-
connan schrieb:
CStoll schrieb:
Nachtrag: Nur eine Idee, die mir gerade gekommen ist:
Wenn ich den COptionDialog nicht lokal anlege, sondern in meine MainDlg-Klasse reinpacke, könnte ich eigentlich von überall an seine Member rankommen. Wäre so etwas praktisch umsetzbar?//noch nicht getestet void OnOption() { if(m_opt.DoModal()!=IDOK) { //*grübelt* Hier müsste ich die alten Werte zurückholen } } void OnSomething() { mach_was_mit(m_opt.m_var1); ... }Ist sicherlich eine bessere Variante als die erste, aber da hast Du ja wieder public Member

Mir ist gerade noch was eingefallen, ich hab mal einen Artikel in der MSDN gefunden der beschrieb wie man seine eigenen DDX Methoden implementiert. Da man an die Standard DDX imho leider keine Referenzen übergeben kann müsste man sich seine eigenen DDX schreiben wo genau das geht.
Wenn Dir die public Memebr egal sind kannst du natürlich auch im Optionsdialog in OnDataExchange die DDX- Aufrufe auf die Variablen des MainDlg umleiten. Ist vieleicht das einfachste.
Also damit kann ich leben - wozu hat man schließlich Freunde?
@VladoBo: Es reicht, einmal auf "Absenden" zu drücken
(*Mod-Skill "Thread aufräumen" aktiviert und den Doppelbeitrag entfernt*
-
CStoll schrieb:
Also damit kann ich leben - wozu hat man schließlich Freunde?

Und wie machst Du es denn jetzt?
-
Noch habe ich es nicht umgesetzt (ich hab' hier noch einige Probleme mit der Datenverarbeitung, da steht die GUI etwas im Hintergrund), aber letztendlich werde ich wohl den oben erwähnten Ansatz verwenden.
-
connan schrieb:
Klingt gut was Du da machst, ich würde auf jedenfall die doc als Zentrale nutzen, die Ini must du ja erst beim beenden neu schreiben oder?
So mach ich das jetzt auch. Aber erst beim Beenden schreiben ist nicht so günstig. Wenn das Hauptprogramm an einer anderen Stelle abschmiert, dann sind die Änderungen weg. Ich spreicher immer sofort.
@CStoll: Also bist Du doch wieder bei Deiner ursprünglichen Lösung. Was anderes ist auch meiner Meinung nach in den meisten Tutorials nicht beschrieben. Wenn man noch Get- und Set-Methoden implementiert kommt man auch von den public-Members weg.