UpdateData(TRUE) funktioniert nicht, sollte es aber tun
-
Wie der Titel schon sagt, die Funktion UpdateData funktioniert nicht. Hierzu der folgende Code:
////////////////////////////////////////////////// // Der folgende Code beinhaltet die Klasse // CExampleDlg, die das Verhalten eines // Dialogfeldes steuert, das tut, was es will. // DECLARE_DYNAMIC() und DECLARE_MESSAGE_MAP() sind // nicht aufgeschrieben, sind aber im originalen // Code vorhanden. // ->CExampleDlg.h ////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////// // CExampleDlg.h //////////////////////////////////////////////////////////////////////////////////////////////////// // (...) class CExampleDlg:public CDialog { // (...) public: ////////////////////////////////////////////////// // (Konstruktor, Destruktor, Resourcenübergabe und // Funktionen, die überflüssig sind...) ////////////////////////////////////////////////// afx_msg void OnCbnSelchangeString(); afx_msg void OnCbnEditchangeString(); ////////////////////////////////////////////////// // (Spezielle Klassen und Definitionen, die nicht // wichtig sind...) ////////////////////////////////////////////////// CString m_CStrString; // String, der den Inhalt eines kombiniertem Listenfeldes speichert private: virtual void DoDataExchange(CDataExchange* pDX); ////////////////////////////////////////////////// // Nachichtentabelle und so weiter ... ////////////////////////////////////////////////// }; //////////////////////////////////////////////////////////////////////////////////////////////////// // CExampleDlg.cpp //////////////////////////////////////////////////////////////////////////////////////////////////// // (...) ////////////////////////////////////////////////// // Überschreibung der Funktion DoDataExchange(), // die nötig für die Funktion UpdateData() ist... ////////////////////////////////////////////////// void CExampleDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); ////////////////////////////////////////////////// // IDC_STRING ist die ID eines kombinierten // Listenfeldes. ////////////////////////////////////////////////// DDX_CBString(pDX,IDC_STRING ,m_CStrString); DDV_MaxChars(pDX,m_CStrString,7); } // (...) ////////////////////////////////////////////////// // Nachrichtentabelle, allerdings nur zwei Einträge // (original sind mehr vorhanden) ////////////////////////////////////////////////// BEGIN_MESSAGE_MAP(CExampleDlg, CDialog) ON_CBN_SELCHANGE (IDC_STRING,&CExampleDlg::OnCbnSelchangeString) // Wenn der Benutzer einen Eintrag AUSWÄHLT... ON_CBN_EDITCHANGE(IDC_STRING,&CExampleDlg::OnCbnEditchangeString) // Wenn der Benutzer einen Eintrag SCHREIBT... END_MESSAGE_MAP() void CExampleDlg::OnCbnSelchangeString() // Hier funktioniert die Funktion UpdateData(TRUE) nicht... { if(!UpdateData(TRUE)) // Standartwert L"Zweiter String". Wenn man jedoch L"Erster String" auswählt, wird der Wert nicht aktualisiert. return; ////////////////////////////////////////////////// // Da es mir einmal zu bunt wurde, habe ich // folgendes Codesegment optional hinzugefügt. // Ergebnis: Keine Rückmeldung des Programms. ////////////////////////////////////////////////// // while(m_CStrString!=L"Erster String") // UpdateData(TRUE); ////////////////////////////////////////////////// // Abfrage nach dem Wert usw ... ////////////////////////////////////////////////// UpdateData(FALSE); } void CExampleDlg::OnCbnEditchangeString() // ... HIER allerdings sehr wohl { if(!UpdateData(TRUE)) // HIER wird der Wert korrekt aktualisiert und verwertet return; ////////////////////////////////////////////////// // Abfrage nach dem Wert usw ... ////////////////////////////////////////////////// UpdateData(FALSE); } // (...)Hier gibt es zwei wichtige Funktionen OnCbnSelchangeString und OnCbnEditchangeString, die beide eine Nachrichtenfunktion bilden, sobald das Ereignis zutrifft. Wenn man den Wert im Kombinationsfeld, mit dem Funktionen und die Variabel m_CStrString verbunden ist, durch eigenen Text (OnCbnSelchangeString(), also Eingabe) verändert, passiert nichts außergewöhnliches. Alles Korrekt.
In der Funktion OnCbnEditchangeString (wenn man einen Eintrag auswählt) funktioniert jdeoch die Funktion UpdateData nicht mehr. Egal, was ich mache, es wird kein neuer Wert angenommen. Durch Debugging & Co habe ich herausgefunden, dass kein neuer Wert angenommen wird. Warum?
Alles ist korrekt, oder etwa doch nicht?
-
So ganz schlau werde ich nicht daraus, aber zwei Dinge zur Kontrolle, die Du vielleicht einmal zum Testen ändern könntest:
1. die Länge Deines Strings von 7 erhöhen oder die Beschränkung ganz rausnehmen
2. die Abfrage von not UpdateData(TRUE) auf UpdateData(FALSE) testen
Gruß
-
1. Nützt nichts, er nimmt den String nicht an.
2. Die Abfrage if(!UpdateData(TRUE))return; ist für den Fall, dass der Benutzer einen fehlerhaften Wert eingibt. Auf if(UpdateData(FALSE))return; wechseln würde nicht bringen, da ich Variabeln und keine Steuerelement aktualisieren will.
-
Was soll das denn bitte bewirken?
if(!UpdateData(TRUE)) // Standartwert L"Zweiter String". Wenn man jedoch L"Erster String" auswählt, wird der Wert nicht aktualisiert. return;Versuch einfach mal nur Ende UpdateData(FALSE). Das sollte eigentlcih funktionieren.
-
Sagt mal, wie lange programmiert ihr schon mit den MFC? UpdateData(TRUE) durchsucht die Steuerelemente nach Werten, speichert diese in den Steuerelementen zugewiesenen Variabeln und aktualisiert somit die Werte für das Programm. Der Rückgabetyp (ist BOOL, eigentlich int) sagt hierbei aus, ob der Vorgang erfolgreich war oder ob das Format fehlerhaft war (Zahlen statt Buchstaben, Zeichengrenze usw.) Bei !=0 lief alles reibungslos, bei 0 kommt eine Fehlermeldung, und da ich keine Lust habe, das Programm mit fehlerhaften Werten arbeiten zu lassen, schicke ich den Befehlszeiger direkt wieder zurück.
UpdateData(FALSE) aktualisiert die Steuerelemente mit dem Wert der Variabeln. Aber um mit den Funktionen arbeiten zu können, brauche ich aktuelle Werte. Die Abfrage wurde im Beispielcode geschnitten, da sie sehr umfangreich und mehr als 300 Zeilen Code fordert.
-
Du hast ein Problem mit dem Laufzeitverhalten von Windows.
CBN_SELCHANGE wird ausgelöst, wenn sich die Daten ändern, aber noch bevor diese gesetzt sind.Du kannst also Dir den Index holen und den Wert aus der ComboBox!
GetCurSel Du wirst sehen, dass dies schon der neue Wert ist.
Du kannst Dir also den neuen Text aus der Box holen.IMHO ist es absoluter Unfug UpdateData in Eventhandlern zu benutzen. Für was willst Du alle Daten austauschen?
Benute einfache Funktionen wie GetCurSel, GetDlgItemText etc. und nicht den Holfzhammer UpdateData.
BTW: GetDlgItemText würde hier auch nicht gehen.
-
Martin Richter schrieb:
Du hast ein Problem mit dem Laufzeitverhalten von Windows.
CBN_SELCHANGE wird ausgelöst, wenn sich die Daten ändern, aber noch bevor diese gesetzt sind.Du kannst also Dir den Index holen und den Wert aus der ComboBox!
GetCurSel Du wirst sehen, dass dies schon der neue Wert ist.
Du kannst Dir also den neuen Text aus der Box holen.IMHO ist es absoluter Unfug UpdateData in Eventhandlern zu benutzen. Für was willst Du alle Daten austauschen?
Benute einfache Funktionen wie GetCurSel, GetDlgItemText etc. und nicht den Holfzhammer UpdateData.
BTW: GetDlgItemText würde hier auch nicht gehen.DANKE. Ich dachte schon, ich werde irre. Ich sitze das ganze Wochenende vor dem Code und erkenne den Fehler nicht. DANKE!
Wenn ich dich recht verstanden habe, gibt GetCurSel den Index und nicht den Inhalt zurück, oder? Muss ich einen Zeiger (GetDlgItem()->GetCurSel()) benutzen oder kann ich eine Control-Variabel mit dem Typ CComboBox verwenden (m_CtrlCBox.GetCurSel()) ?
-
Es geht beides. Ich verwende immer gebundene Member Variablen. Anschließend kannst Du mit dem Index (sofern nicht CB_ERR , -1) einfach GetLBText ausführen und jetzt neuen selektierten Text benutzen.