Problem mit Eingabefeld und EN_CHANGE/UpdateData-Behandlung



  • Hallo,

    mein Problem betrifft die EN_CHANGE-Behandlung mit automatischem UpdateData(true)-Aufruf.

    Prinzipiell soll das so funktionieren, dass der Benutzer ein Eingabefeld beschreibt, und daraufhin per EN_CHANGE automatisch ein UpdateData(true)-Aufruf ausgelöst wird.
    Leider prüft die EN_CHANGE-Funktion nicht, ob überhaupt schon eine sinnvolle Zahl in dem Feld steht. Tippt man beispielsweise 1.5, also "1", ".", "5" ein, dann übernimmt er die 1, beim Komma springt der Cursor ganz nach vorn und die 5 landet dann vor der 1.

    Also: Eingabe=1.5, Ausgabe=51.

    Was kann man da machen?
    Momentan muss man 15 eingeben und dann den Dezimalpunkt in die Mitte setzen. Aber das kann ja nicht der Weisheit letzter Schluss sein. 😞
    Der Datentyp des Feldes steht übrigens auf double.

    Jemand eine Idee?

    Gruß, Thomas.



  • ich habe mir das abgewöhnt datentypen für edit-felder zu vergeben, mag das irgendwie nicht 😉

    wenn deine OnUpdate() methode aufgerufen machst du einfach das:

    CString cWert;
    float fDerFloatWert;
    
    GetDlgItem(IDC_DEIN_EDIT)->GetWindowText(cWert);
    fDerFloatWert = atof(cWert);
    

    und schon haste deine eingabe 👍



  • Zeig mal deinen Code.
    Aber EN_CHANGE ist auch nicht so optimal für solche Prüfungen.

    Wenn du dir eine Klasse anschaust, wo sowas eingebaut ist, dann ist das IMHO in OnChar bzw. OnKeyDown. 🙂
    (Mein Favorit ist die Sammlung um CAMSEdit von Codeproject.)



  • Jo, meine Lösung geht in die Richtung von Red Skall:

    void CheckAndUpdate(int ID)
    {
    	// Eingabestring holen
    	CString str;
    	GetDlgItem(ID)->GetWindowText(str);
    
    	if (GetDlgItem(ID)->GetWindowTextLength() > 0)
        if(str.GetAt(str.GetLength()-1) != '.') // falls letztes Eingabezeichen kein Dezimalpunkt
    	{
    		if(str=="0")                        // falls 0 eingegeben
    			DoUpdate(true);
    		else                                
    		{
    			// Konvertierung String2Double
    			double x = atof(str);
    			if(x!=0)                        // falls String2Double erfolgreich
    				DoUpdate(true);
    		}
    	}
    }
    


  • EN_CHANGE ist m.E. günstiger, auch wenn es in erster Näherung an den Parent geschickt wird (was ist z.B. mit rechtsklick + paste?)
    Nur würd ich in *jedem* Change-Handler die Finger von UpdateData lassen - UpdateData ist einfach nicht dafür gemacht (und leider auch nicht flexibel genug, um angepaßt zu werden).

    Ich hab' bereits eine beachtliche Sammlung von Methoden der Sorte GetWindowDouble, und mogel' mich so durch 🙂



  • Kannst Du das etwas genauer ausführen? Ich habe mit UpdateData bisher keine Probleme gehabt. Das einzige, was ich etwas unflexibel finde, ist dass immer der gesamte Variablensatz aktualisiert wird.
    Meine CheckAndUpdate-Methode wird von dem EN_CHANGE Ereignis ausgelöst und ich habe bisher noch keinen Bedienablauf gefunden, bei welchem es Probleme gibt.

    Gruß, Thomas.



  • EN_CHANGE - ich habe bisher noch keinen Bedienablauf gefunden, bei welchem es Probleme gibt

    z.B.: Abhängig von getippten / ausgewählten Text soll sich der Inhalt eines anderen Controls ändern:

    UpdateData(true);  // get data
    ... // calculate side effects
    UpdateData(false); // write back
    

    das bringt natürlich die Auswahl im Edit total durcheinander.

    Des weiteren sind di Windows Controls sehr inkonsistent: manche feuern Change Notifications auch, wenn man im Programm was ändert, andere nicht. Beides erfordert manchmal ein "Finetuning" welche Controls man updated.

    Außerdem find' ich die Validation-Messageboxes nicht grad' Klasse.

    UpdateData() ist perfekt für einen modalen Dialog mit unabhängigen Daten (wenn ich das wirklich mal brauche bin ich immer überrascht wie schön das geht 🙂 ) Leider ist das nur selten mein Problem...


Anmelden zum Antworten