UpdateData() in mehreren Dialogen?
-
Ich habe eine MFC-Anwendung (Windows XP, VS.NET 2003) und darin eine CTabCtrl. Diese funktioniert auch wunderbar, ich habe für jeden Reiter eine eigene Klasse und einen eigenen Dialog. Nun habe ich eine Funktion, die diverse Felder auf den verschiedenen Tab-Dialogen aktualisieren soll, wobei die Funktion im Hauptdialog aufgerufen wird. Wie kann ich nun quasi dialogübergreifend aktualisieren? Ich habe es bereits so versucht (Funktion eines Dialogs, der aktualisiert werden soll):
void CMyClass::Update() { this->SetDlgItemText(IDC_EDIT, m_sEdit); //UpdateData(false); // (Alternativ) }Im Hauptdialog sieht es so aus:
CMyClass hWnd; hWnd.m_sEdit = "Hallo Welt"; hWnd.Update();m_sEdit ist eine Value-Variable einer Editbox auf einem der Dialoge. Es kompiliert zwar, jedoch kommt dann zur Laufzeit der Fehler "Debug Assertion Failed". Hilfe.
zony
-
Objekt.EditValueVar = "34 Hosen mit Kraut!"
Objekt.UpdateData(TRUE);// von variable ins Edit rein z.B.
-
Abgesehen davon, dass UpdateData(true) vom Dialog in die Variable (und nicht umgekehrt, so wie ich es möchte) schreibt, habe ich das auch bereits probiert. Funktioniert leider nicht.

zony
-
Nur mal so ein unverbindlichen Tipp:
Schau mal in der Hilfe nach was das "true" bei UpdateData bewirkt....
-
Bin ich jetzt bekloppt oder was?
Call this member function to initialize data in a dialog box, or to retrieve and validate dialog data.
...
bSaveAndValidate
Flag that indicates whether dialog box is being initialized (FALSE) (also VARIABLE->DIALOG) or data is being retrieved (TRUE) (also DIALOG->VARIABLE).Ich habe die Funktion schon 1000x benutzt und wenn ich den Parameter auf TRUE setze, werden die Daten vom Dialog in die Membervariable geschrieben, ist der Parameter FALSE wird der Dialog mit den Werten von der Membervariable aktualisiert. So hat es zumindest in etlichen anderen Programmen funktioniert. :p Kann vielleicht mal einer konkret werden?
zony
-
zony schrieb:
I
Im Hauptdialog sieht es so aus:
CMyClass hWnd; hWnd.m_sEdit = "Hallo Welt"; hWnd.Update();m_sEdit ist eine Value-Variable einer Editbox auf einem der Dialoge. Es kompiliert zwar, jedoch kommt dann zur Laufzeit der Fehler "Debug Assertion Failed". Hilfe.
zony
Wieso erstellst du hier eine Instanz deines Reiters. Ich dachte die gibt es schon.
Wenn ja brauchst du eine Zeiger darauf.
-
Ich verstehe nicht ganz. Ich habe in meinem Projekt einfach mehrere Dialoge (und damit mehrere Klassen), die über die Klasse CMyTabCtrl in einem TabCtrl "zusammengefasst" werden. In der Hauptdialogklasse werden lediglich Reiternamen über eine Membervariable von CMyTabCtrl eingetragen. Wie gehe ich denn nun genau vor? Ich habe schon einiges für die Konsole gemacht, nur die MFC ist relativ Neuland für mich (lese Visual C++ von Frank Budszuhn, richtig gut das Buch) ...

Danke vorab!zony
-
Hat doch nichts mit der MFC zu tun.
Wei du es machst erstellst du eine Instanz deines Dialogs.
IMHO gibt es aber bereits eine Instanz da die vermutlich bei Starten des Programmes erstellt wird.
Du hättest vieleicht mal scheuen sollen wo dein Programm eine Zugriffsfehler liefert. Wie soll man auch einen Dialog updaten den es in der erstellten Klasse nicht gibt.Du musst dir also eine Zeiger auf die bereits existierende holen und nicht einfach eine neue erstellen.
Die ist also ein C++-Problem.
-
Ah, nun verstehe ich das Problem! Ich habe in der OnInitDialog-Funktion des Hauptdialogs einen Aufruf, der CMyTabCtrl über eine Membervariable (auf das TabCtrl) initialisiert. Dort werden im Konstruktor die drei Dialoge "erzeugt" und in einem Pointer-Array vom Typ CDialog ("CDialog *pPages[3];") gespeichert:
pPages[0] = new CMyDialog1; // etc. für die anderen ReiterWie kann ich nun von einer Funktion aus der Hauptdialogklasse auf die Objekte zugreifen, also wie komme ich an die Zeiger, die ich benötige? Danke!!

zony
-
Du hast doch schon eine Instanz im Hauptdialog. Auf die musst du zugreifen. Ich empfehle dir aber das in C++ nochmals durchzulesen da dies essenzielle dinge sind die man als C++_Programmierer wissen sollte.
Sollte du es nicht hinbekommen werde ich deinen Thread nach c++ verschieben.
-
Ich habe hauptsächlich strukturiert programmiert (C), von C++ kenne ich wirklich nur die Grundlagen, aber es wird langsam mehr. Wenn es so essentiell ist, dann weißt du das doch sicher. Wieso kannst du das dann nicht sagen?
Trotzdem danke für die bisherige Hilfe.zony
-
Was soll ich dir noch sagen. Habe es ja schon. Du hast bereits eine Instanz. Diese musst du benutzen. Um es in C auszudrücken:
"Du legst ein Variable mit Inhalt an. In einer anderen Funktion legst du eine neue Variable mit Inhalt an welche genauso heißt wie die andere weil du glaubst dann kommst du an den Inhalt."
So hast du es gemacht.
Was du brauchst ist aber die erste Variable. (In deinem Fall also die Klasseninstanz)
Wenn ich dir die Lösung direkt sagen würde wäre das "AHA-Erlebniss" bei dir nicht da und somit der Lerneffekt gering.
-
Ich kapier nicht worauf du hinaus willst. In meiner OnInitDialog-Funktion habe ich doch nur die Membervariable vom Typ CMyCtrlTab vom TabCtrl-"Baustein" des Hauptdialogs, welche die Init()-Funktion der CMyTabCtrl-Klasse aufruft ("m_MyTabCtrl.Init();" - ich benutze diese Klasse hier). Dort werden doch die einzelnen Seiten erst im Konstruktor erzeugt. Ich habe also nur die Membervariable im Hauptdialog. Folgender Ansatz funktioniert auch nicht so ganz (selber Crash):
CDialog *pDlg; pDlg = m_MyTabCtrl.m_tabPages[2]; // in 2 wird der Dialog mit dem Edit-Feld erzeugt pDlg->UpdateData(false);Geht das wenigstens in die richtige Richtung?
"Du legst ein Variable mit Inhalt an. In einer anderen Funktion legst du eine neue Variable mit Inhalt an welche genauso heißt wie die andere weil du glaubst dann kommst du an den Inhalt."
Ja, so in etwa (auch wenn sich das in C total absurd anhört
). Ich dachte eben, dass wenn ich mit dieser Instanz ein UpdateData() ausführe, dann die Dialoge mitaktualisiert werden. Aber so wie du das beschreibst ist das natürlich Bullshit. 
zony
-
Das selbe hört sich auch in C++ total Absurd an

Wieso möchtest du Dialoge aktualisieren,die gerade nicht Aktiv sind? Wäre es nicht
einfach die Werte in die membervariablen zu schreiben und wenn der Dialog den Focus
erhält einfach die Daten aktualisieren?
-
Ich habe einen Reiter, in dem ein Editfeld ist. Diesen wähle ich an und dann klicke ich im "Hauptdialog" auf einen Button und dann soll das Editfeld gefüllt werden. Dann hat dieses bzw. dessen Dialog ja nicht den Focus (wenn ich den Reiter vorher wechsle sieht das vielleicht anders aus). Der Knopf liest Daten von der seriellen Schnittstelle, welche diverse Informationen auf die verschiedenen Reiter verteilen soll. Wenn ich also den Connect-Button drücke, sollen die Daten laufend auf allen Seiten aktualisiert werden, so dass ich, egal ob ich gewechselt habe (Focus) oder nicht, aktuelle Informationen präsentiert bekomme. Daher möchte ich die Dialoge auf allen Seiten aktualisieren, sobald neue Daten von der Schnittstelle verfügbar sind.
zony
-
Wie siehts denn nun aus? Unix-Tom?

zony
-
Also es sind Grundlagen und keiner kann mir helfen? Schade eigentlich...

zony
-
Du hast in einer deiner Hauptklassen bereist Klasseninstanzen deiner Dialoge. Richtig?
Jetzt brauchst du nur diese Instanz nehmen und kannst damit auf den Dialog zugreifen.
Was du gemacht hast ist eine neue Instanz erstellt.
Da deine Dialogklasse aber bereist existiert kannst du dir entweder den Zeiger darauf holen oder in deiner Hauptklasse mittels der Instanzvar auf den Dialog zugreifen.
-
Ja, aber soweit waren wir ja bereits, siehe dieses Posting:
Ich kapier nicht worauf du hinaus willst. In meiner OnInitDialog-Funktion habe ich doch nur die Membervariable vom Typ CMyCtrlTab vom TabCtrl-"Baustein" des Hauptdialogs, welche die Init()-Funktion der CMyTabCtrl-Klasse aufruft ("m_MyTabCtrl.Init();" - ich benutze diese Klasse hier). Dort werden doch die einzelnen Seiten erst im Konstruktor erzeugt. Ich habe also nur die Membervariable im Hauptdialog. Folgender Ansatz funktioniert auch nicht so ganz (selber Crash):
CDialog *pDlg; pDlg = m_MyTabCtrl.m_tabPages[2]; // in 2 wird der Dialog mit dem Edit-Feld erzeugt pDlg->UpdateData(false);Geht das wenigstens in die richtige Richtung?
Hier erzeuge ich doch keine neue Instanz sondern erstelle einen Zeiger vom Typ CDialog, welche auf das entsprechende Objekt zeigen sollte. Crashed aber genauso. Biete mir doch bitte eine Lösung an.

zony
-
Wieso soll es auch. Eine Registerkarte ist kein Dialog sondern ein Control.
Wenn dann musst du hier einen Zeiger auf die Controlklasse erstellen.
Da du aber sowieso bereits das Handle hast (m_MyTabCtrl.m_tabPages[2]) warum willst du dann nochmals einen Zeiger erstellen.