none
Eingabefeld mit Kommazahl RRS feed

  • Frage

  • Hallo an alle,

    ich habe in einem Dialog ein Eingabefeld (Edit Control), bei dem nur Kommazahlen erlaubt sein sollen. In den Eigenschaften des Eingabefeldes bin ich soweit, dass das mit einer Ganzzahl funktioniert.

    Hier die Eigenschaften dazu:

    Leider kann ich damit aber keine Kommastellen (weder mit Punkt noch mit Komma) eingeben.

    Was muss ich tun, damit im Eingabefeld Zahlen mit Kommastellen möglich sind?

    Danke im Voraus und viele Grüße

    Bernd

    Donnerstag, 28. März 2019 12:42

Antworten

  • Ich habe jetzt die Eigenschaft Number auf FALSE gesetzt, eine Membervariable mit dem Typ double für das Eingabefeld gesetzt und eine Funktion für EN_CHANGE berücksichtigt. Soweit so gut.

    Wenn ich nun im Eingabefeld den Wert 91,5 eingebe und den Inhalt der Membervariable mit UpdateData(TRUE) aktualisiere, wird der Wert nach dem Komma abgeschnitten. Es wird hier statt dem Komma ein Punkt erwartet.

    Wie kann ich in der Funktion für EN_CHANGE den vom Anwender eingegebenen Wert 91,5 (Komma) ermitteln?

    Setze direkt beim Start deiner Anwendung das korrekte oder gewünschte Laufzeitgebietsschema, dann wird Punkt und Komma korrekt behandelt.

    - Gruß Florian


    Freitag, 29. März 2019 10:55

Alle Antworten

  • Hallo,

    du musst das EditCtrl normal definieren, also mit "Number" = False. Mit Number=True werden nur Zahlen angenommen.

    Nun kann man wieder alles in das Feld eingeben. Um das zu verhindern, könntest du EN_CHANGE des EditCtrl abfangen und die Eingabe des Benutzers analysieren und entsprechend zu ändern. Oder du machst das erst nach dem Killfocus. Ich analysiere eine Eingabe immer erst mit dem Killfocus und korrigiere die Eingabe entsprechend bzw. melde dem Benutzer, dass er da was falsches eingegeben hat. Dann setze ich den Focus wieder auf das EditCtrl, damit der Benutzer was richtiges eingeben kann.

    Man sollte dem Benutzer immer die Möglichkeit geben, alles was er will einzugeben, und erst dann prüfen, ob das auch sinnvoll war, was er eingegeben hat. Nur wenn es wirklich nur Zahlen sein dürfen, kann man sofort die Eigenschaft Number setzen. Ansonsten muss man selbst die Eingabe analysieren und entsprechend drauf reagieren.

    Gruß Guido

    • Als Antwort vorgeschlagen Florian Haupt Donnerstag, 11. April 2019 07:53
    Donnerstag, 28. März 2019 14:30
  • Hallo Guido,

    danke für Deine Informationen.

    Ich habe jetzt die Eigenschaft Number auf FALSE gesetzt, eine Membervariable mit dem Typ double für das Eingabefeld gesetzt und eine Funktion für EN_CHANGE berücksichtigt. Soweit so gut.

    Wenn ich nun im Eingabefeld den Wert 91,5 eingebe und den Inhalt der Membervariable mit UpdateData(TRUE) aktualisiere, wird der Wert nach dem Komma abgeschnitten. Es wird hier statt dem Komma ein Punkt erwartet.

    Wie kann ich in der Funktion für EN_CHANGE den vom Anwender eingegebenen Wert 91,5 (Komma) ermitteln?

    Viele Grüße

    Bernd

    Freitag, 29. März 2019 06:56
  • Hallo Guido,

    danke für Deine Informationen.

    Ich habe jetzt die Eigenschaft Number auf FALSE gesetzt, eine Membervariable mit dem Typ double für das Eingabefeld gesetzt und eine Funktion für EN_CHANGE berücksichtigt. Soweit so gut.

    Wenn ich nun im Eingabefeld den Wert 91,5 eingebe und den Inhalt der Membervariable mit UpdateData(TRUE) aktualisiere, wird der Wert nach dem Komma abgeschnitten. Es wird hier statt dem Komma ein Punkt erwartet.

    Wie kann ich in der Funktion für EN_CHANGE den vom Anwender eingegebenen Wert 91,5 (Komma) ermitteln?

    Viele Grüße

    Bernd

    Hallo,

    du musst die Variable für das EditCtrl als CString definieren, das double würde ich auch behalten als eigenständige Member Variable. In EN_CHANGE musst du dann aus dem , ein Punkt machen und das dann in dein double umwandeln.

    double toDbl(CString sz)
    {
    	static int i;
    	if (sz.GetLength() == 0) return 0.;
    	i = sz.Find(_T(','));
    	if (i >= 0) sz.SetAt(i, _T('.'));
    	return _tstof(sz);
    }

    Gruß Guido


    Freitag, 29. März 2019 07:40
  • du musst die Variable für das EditCtrl als CString definieren, das double würde ich auch behalten als eigenständige Member Variable. In EN_CHANGE musst du dann aus dem , ein Punkt machen und das dann in dein double umwandeln.

    Nein, das machen die DDX Routinen schon richtig, wenn die Lokalisierung korrekt gesetzt ist, d. h. es darf und sollte eine double Variable gebunden werden.


    - Gruß Florian


    Freitag, 29. März 2019 10:46
  • Ich habe jetzt die Eigenschaft Number auf FALSE gesetzt, eine Membervariable mit dem Typ double für das Eingabefeld gesetzt und eine Funktion für EN_CHANGE berücksichtigt. Soweit so gut.

    Wenn ich nun im Eingabefeld den Wert 91,5 eingebe und den Inhalt der Membervariable mit UpdateData(TRUE) aktualisiere, wird der Wert nach dem Komma abgeschnitten. Es wird hier statt dem Komma ein Punkt erwartet.

    Wie kann ich in der Funktion für EN_CHANGE den vom Anwender eingegebenen Wert 91,5 (Komma) ermitteln?

    Setze direkt beim Start deiner Anwendung das korrekte oder gewünschte Laufzeitgebietsschema, dann wird Punkt und Komma korrekt behandelt.

    - Gruß Florian


    Freitag, 29. März 2019 10:55
  • Nein, das machen die DDX Routinen schon richtig, wenn die Lokalisierung korrekt gesetzt ist, d. h. es darf und sollte eine double Variable gebunden werden.



    Hatte bei mir aber trotz richtiger Lokalisierung nicht funktioniert. Das EditCtrl wollte immer einen Punkt statt des Kommas. Könnte ein Windows Problem sein, hab ich aber nicht weiter analysiert; der Workaround reichte mir aber.

    Gruß Guido


    Freitag, 29. März 2019 10:57
  • Hatte bei mir aber trotz richtiger Lokalisierung nicht funktioniert. Das EditCtrl wollte immer einen Punkt statt des Kommas. Könnte ein Windows Problem sein, hab ich aber nicht weiter analysiert; der Workaround reichte mir aber.

    Haben wir seit Jahren keine Probleme mit - kommt das richtige locale zurück, wenn du es in EN_CHANGE prüfst?
    Es ist auch möglich die Lokalisierung nur für den Datenaustausch der Dialoge zu setzen oder temporär zu ändern.


    - Gruß Florian

    Freitag, 29. März 2019 11:06
  • Hallo Guido, hallo Florian,

    danke für eure Informationen.

    Mit folgenden Code-Zeilen ist ein Komma statt einem Punkt bei einer Membervariablen vom Typ double bei meiner Anwendung erlaubt:

    char *old_locale;
    old_locale = setlocale(LC_ALL, "de-DE");
    

    Viele Grüße

    Bernd

    Montag, 1. April 2019 09:31

  • Mit folgenden Code-Zeilen ist ein Komma statt einem Punkt bei einer Membervariablen vom Typ double bei meiner Anwendung erlaubt:

    char *old_locale;
    old_locale = setlocale(LC_ALL, "de-DE");


    Das ist richtig. Du kannst die vom Nutzer verwendete Einstellung auch ermitteln:
    WCHAR szISOLang[3] = { 0 };
    WCHAR szISOCountry[3] = { 0 };
    
    ::GetLocaleInfo(LOCALE_USER_DEFAULT,
      LOCALE_SISO639LANGNAME,
      szISOLang,
      sizeof(szISOLang) / sizeof(WCHAR));
    
    ::GetLocaleInfo(LOCALE_USER_DEFAULT,
      LOCALE_SISO3166CTRYNAME,
      szISOCountry,
      sizeof(szISOCountry) / sizeof(WCHAR));
    
    
    
    Bei Deutsch-Deutschland, ergibt der obige Code für szISOLang "de" und für szISOCountry "DE", für setlocale dann mit "-" zusammensetzen.

    - Gruß Florian

    Montag, 1. April 2019 10:15
  • Hallo Florian,

    danke für Deine Informationen.

    ich komme jetzt soweit zurecht. Ich lasse die Anwender vor der Erstinstallation einmalig entscheiden, ob sie den double-Wert mit Komma oder Punkt eingeben möchten. Dementsprechend verwende ich dann die Funktion setlocale in meiner Funktion OnInitDialog.

    Danke nochmals an alle und viele Grüße

    Bernd

    Montag, 1. April 2019 12:32
  • Hallo Bernd

    Also ich habe die Erfahrung gemacht, dass die User je nach kultureller und technischer Vorprägung entweder "." oder "," als Kommatrennzeichen eingeben, weshalb ich IMMER bei Dialogen, die der "gemeine Anwender" bedienen soll/darf, beides zulasse, d.h. ich lese das Edierfeld als String aus und analysiere diesen dann selbst.

    In weiterer Folge ist es dann auch nützlich, den Eingabewert auf bestimmte Grenzen zu untersuchen. Ein klassisches Beispiel hierzu sind Eingabefelder für Gewichte in Tonnen. Ungezählte Male hatte ich dann Anwender, die das Gewicht in kg eingegeben hatten … also war der nächste Schritt, zu überprüfen, ob es überhaupt möglich ist, ein Gefäß mit 12450 TONNEN zu beladen … nein, also müssen es kg sein.

    Grüße

    FireHeart

    Donnerstag, 23. Mai 2019 14:50
  • Hallo FireHeart

    Also ich habe die Erfahrung gemacht, dass die User je nach kultureller und technischer Vorprägung entweder "." oder "," als Kommatrennzeichen eingeben, weshalb ich IMMER bei Dialogen, die der "gemeine Anwender" bedienen soll/darf, beides zulasse, d.h. ich lese das Edierfeld als String aus und analysiere diesen dann selbst.

    Genau darum holt sich ein Programm die Einstellungen vom Betriebssystem, um die kulturellen Einstellungen zu berücksichtigen.
    Wie interpretierst Du denn ein Tausender-Trennzeichen, bzw. wie unterscheidest du zwischen Tausender- und Dezimaltrennzeichen? Nur ein Beispiel "1.256", wird das jetzt als 1256 oder 1,256 eingelesen?
    Sicher, mit einer Plausibilitätsprüfung kann eventuell der eine oder andere Wert ausgeschlossen werden, wenn die Grenzen das denn zulassen. Der "gemeine Anwender" erwartet regelmäßig, dass die "kulturellen"-Einstellungen des Betriebssystem berücksichtigt werden, da er dies aus sämtlichen anderen Anwendungen auch so gewohnt ist - dies so nervig weit, dass man z. B. beim Excel-Import von CSV Dateien darauf achten muss unter welchen Einstellungen diese erzeugt wurden und diese ggfls. in der eigenen Umgebung kurzfristig passend ändert.
    Der Standard sollte die gewohnte Einstellung sein, ansonsten halte ich eine Auswahl wie von Bernd vorgesehen für Sinnvoll, dies verhindert auch Fehlinterpretationen und macht falsche Eingaben nachvollziehbar. Für Anpassungen könnte auch der entsprechende Betriebssystem-Dialog aufgerufen werden.

    In weiterer Folge ist es dann auch nützlich, den Eingabewert auf bestimmte Grenzen zu untersuchen. Ein klassisches Beispiel hierzu sind Eingabefelder für Gewichte in Tonnen. Ungezählte Male hatte ich dann Anwender, die das Gewicht in kg eingegeben hatten … also war der nächste Schritt, zu überprüfen, ob es überhaupt möglich ist, ein Gefäß mit 12450 TONNEN zu beladen … nein, also müssen es kg sein.

    Die Prüfung auf sinnvolle Werte ist natürlich immer eine gute Idee. Warum erlaubst du nicht Eingaben wie "12.450,00 kg" oder "12,450 t"? Wenn es eh als String gelesen wird, wäre es doch ein leichtes auch die Einheit zu parsen.


    - Gruß Florian

    Freitag, 24. Mai 2019 07:40
  • Hallo Florian

    Die kulturellen Unterschiede der Bediener sind ja bereits an einer einzigen Anlage das größte Problem. An EINEM PC geben unterschiedliche Menschen mit unterschiedlicher "Prägung" Daten ein. Da wird wohl keiner jedes mal bei Beginn seiner Schicht, die "Regional Settings" auf seine Bedürfnisse umstellen.

    Tausender Trennzeichen sind zwar schön zu lesen, aber für mich das allerschlimmste Greuel, weil nämlich genau das passieren kann, was du angesprochen hast. Dies ist der Grund, warum ich auf meinen PCs immer das Tausender-Trennzeichen auf Hochkomma (') stelle, damit man keinesfalls mit den normalen Kommas oder Punkten kollidiert.

    Grüße

    FireHeart

    Freitag, 24. Mai 2019 08:59
  • Die kulturellen Unterschiede der Bediener sind ja bereits an einer einzigen Anlage das größte Problem. An EINEM PC geben unterschiedliche Menschen mit unterschiedlicher "Prägung" Daten ein. Da wird wohl keiner jedes mal bei Beginn seiner Schicht, die "Regional Settings" auf seine Bedürfnisse umstellen.

    Nein, der Bediener/Anwender meldet sich mit seinem Konto an, hat dann folglich seine Einstellungen, da muss nicht jeden Tag Neu eingestellt werden.

    Vermutlich denkst Du an einen bestimmten Sonderfall (geschrieben hast du allerdings "IMMER"), diesen kann ich aber nicht beurteilen und noch weniger Einschätzen wie akzeptabel unterschiedliche Eingaben sind - Mir ist bewusst das es Gründe geben kann von den angebotenen Möglichkeiten des Betriebssystems abzuweichen, dies sicher aber nicht pauschal, und ich gehe einfach davon aus, dass die Entscheidung, die du da getroffen hast, für deinen Fall sinnvoll ist und auch entsprechenden kommuniziert ist.


    - Gruß Florian

    Freitag, 24. Mai 2019 09:51

  • Nein, der Bediener/Anwender meldet sich mit seinem Konto an, hat dann folglich seine Einstellungen, da muss nicht jeden Tag Neu eingestellt werden.

    Vermutlich denkst Du an einen bestimmten Sonderfall

    Hm,

    nur mal so am Rande. Es soll ja noch PCs geben, wo die Benutzerkontensteuerung nicht genutzt wird. Und dann nutzen viele Anwender die gleiche Windows Umgebung. Das wäre also ein Sonderfall-PC.

    Gruß Guido


    PS: Ich gehöre auch zu der Gattung Programmierer, wo das Programm jede Eingabe auf Plausibilität prüfen soll. Benutzer geben immer ein, was sie wollen, das Programm sollte also den DAU, den dümmsten anzunehmenden Benutzer, auch verarbeiten können. Ich verlasse mich nicht auf Windows Einstellungen.
    Freitag, 24. Mai 2019 10:23
  • Hallo Guido

    nur mal so am Rande. Es soll ja noch PCs geben, wo die Benutzerkontensteuerung nicht genutzt wird. Und dann nutzen viele Anwender die gleiche Windows Umgebung. Das wäre also ein Sonderfall-PC.

    Siehst Du das als Standard? Das finde ich dann doch etwas befremdlich. Mir fällt für sowas zum Beispiel der Geldautomat ein, und Nein, dort kann man nicht einfach einen Punkt für ein Komma eingeben - warum das so ist, kann man sich wohl vorstellen und faszinierenderweise bietet auch so ein "Sonderfall-PC", wie ein Geldautomat, eine Umschaltung der Sprache an.
    Das Ignorieren von Standards führt zu Missverständnissen und Falscheingaben, das Beispiel habe ich bereits genannt. Das andere Problem beim Ignorieren von Standards ist der Mangel im Bedienkomfort - unsere Nutzer würden sich über ein entsprechendes Programmverhalten beschweren und das zu Recht. Vielleicht nicht in jedem Fall relevant, aber eine Zahl um den Faktor 1000 verschieden zu interpretieren, weil ich Einstellungen ignoriere kann mitunter fatal sein.
    Ich habe bereits eingeräumt, dass es Gründe geben kann von den Möglichkeiten keinen Gebrauch zu machen. Ich möchte aber vermeiden, dass hier einer liest und denkt es wäre eine gute Idee, die Betriebssystem-Einstellungen grundsätzlich zu ignorieren. Die Einstellungen für das Dezimaltrennzeichen sind da und sollten auch genutzt werden, wenn denn keine guten Gründe dagegen sprechen.

    PS: Ich gehöre auch zu der Gattung Programmierer, wo das Programm jede Eingabe auf Plausibilität prüfen soll. Benutzer geben immer ein, was sie wollen, das Programm sollte also den DAU, den dümmsten anzunehmenden Benutzer, auch verarbeiten können. Ich verlasse mich nicht auf Windows Einstellungen.

    Das ist auch richtig und wichtig, sollte aber im Umkehrschluss nicht bedeuten die gewünschten Benutzereinstellungen zu ignorieren. Etwas anderes zu machen, als der Anwender aufgrund des üblichen Verhaltens eines Windows Programmes erwarten kann, führt zu mehr fehlerhaften Eingaben, deren Grund auch noch für den Anwender in-transparent sind - dieser kann unter Umständen gar nicht Nachvollziehen was dort falsch gelaufen ist.

    Die DDX Routinen machen das ja, sie prüfen die Eingaben und da wo es nötig ist, kann ich diese erweitern.


    - Gruß Florian

    Freitag, 24. Mai 2019 11:22