Entwickler-Ecke
Windows API - Dezimalseparator wird willkürlich zurückgesetzt
Biergeneral - Mo 13.10.08 00:12
Titel: Dezimalseparator wird willkürlich zurückgesetzt
Hallo,
ich hab folgendes Problem(reproduzierbar):
Ich habe in meiner Anwendung den Dezimalseparator auf '.' gesetzt, damit alles "internationalisiert" angezeigt wird ;-)
Soweit sogut. Funktioniert auch alles bis zu einem bestimmten Punkt:
Verändert sich irgendwas an den Windowseinstellungen, wird der Dezimalseparator, (ohne eigenes einwirken!) zurück auf Komma gesetzt.
Mit Veränderung der Windowseinstellungen mein ich jetzt allerdings völlig willkürliche Sachen..
Das Beispiel was ich angefügt hab, verdeutlicht das Problem anhand der Taskleisteneigenschaft "Taskleiste fixieren"
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
| procedure TestBug; var LOCALE_SEPARATOR: Char; c: integer; begin LOCALE_SEPARATOR := GetLocaleChar(GetThreadLocale, LOCALE_SDECIMAL, '.');
if LOCALE_SEPARATOR = ',' then DecimalSeparator := '.' else DecimalSeparator := ',';
ShowMessage('Der Dezimalseparator ist jetzt auf "' + DecimalSeparator + '" gesetzt und wird nicht mehr verändert!');
ShowMessage('Noch stimmt alles! Jetzt klicke mal mit der Rechten Maustaste auf das Startmenü, und dann auf Tastkleiste fixieren ' +#13#10#13#10'Fortfahren?');
if DecimalSeparator = LOCALE_SEPARATOR then ShowMessage('Jetzt ist er wieder zurückgesetzt worden! Und warum das Ganze?' +#13#10'Bei Konsolenanwendungen passiert das übrigens nicht!') else ShowMessage('Dezimalseparator ist immernoch korrekt') end; |
Steckt dahinter ein "sinnvoller" bzw. gezielter Aufruf durch eine Windowsfunktion den man unterbinden kann? Oder ist das ganz einfach nur ein Bug?
Grüße vom Biergeneral 8)
jaenicke - Mo 13.10.08 02:08
Diese Variablen werden aus dem System ausgelesen und das ist eigentlich auch gut so, denn ich würde ein Programm, das diese von mir gemachten Einstellungen ignoriert oder sogar verändert normalerweise direkt wieder löschen.
Schließlich sind diese systemweiten und anwendungsübergreifenden Einstellmöglichkeiten ja nicht zum Spaß da.
Wenn ich in einer Anwendung mutwillig diese Einstellungen ignorieren will, dann benutze ich die einfach nicht zur Ausgabe sondern formatiere die Ausgabe wie ich es will, wo ist das Problem? :nixweiss:
Hidden - Mo 13.10.08 05:48
jaenicke hat folgendes geschrieben : |
| wo ist das Problem? :nixweiss: |
Sehe ich eigentlich auch so. Zumal
ungefragt sollte es nicht verändert werden.
Aber als Einstellung, die vom User getroffen werden kann, sollte das doch von einem Programm systemweit eingestelt werden können(ich bezweifle, dass man dazu Administratorrechte braucht.. Obwohl sicher niemand weiß, wie man es ohne Programm zurückstelt, das lästig werden könnte und vielleicht ganz sinnvoll sein könnte, wenn Programme Mist machen :roll:).
Imho sind die Methoden um StrToFloat ohnehin ohne weiteres noch nicht optimal. Der Programmierer sollte beim Einlesen einer Float-Zahl im deutschsprachigen Raum ein StrReplace auf DecimalSeperator durchführen.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| function ReadMyFloat(const S: String): Extended; const DecSeps: Array[Boolean] of Char = ['.', ',']; begin StrReplace(S, DecSeps[DecimalSeperator = DecSeps[false]], DecimalSeperator, [rfReplaceAll]); result := StrToFloat(S); end; |
mfG,
Delete - Mo 13.10.08 08:25
Delphi-Quelltext
1:
| Application.UpdateFormatSettings := False; |
| Zitat: |
| Mit UpdateFormatSettings können Sie die automatische Aktualisierung von Formateinstellungen steuern. Der Standardwert true ist im Konstruktor eingestellt. UpdateFormatSettings wird immer dann überprüft, wenn die Anwendung eine WM_WININICHANGE-Botschaft empfängt. |
Biergeneral - Mo 13.10.08 11:12
Ahh! Letzteres habe ich gesucht.
Im Normalfall habt ihr Recht was die formatierte Ausgabe angeht. Da würde ich die Ausgabe wie folgt angehen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| var FormatSettings: TFormatSettings; begin GetLocaleFormatSettings(LOCALE_USER_DEFAULT, FormatSettings); FormatSettings.DecimalSeparator := '.';
StrToFloat(SomeStr, formatSettings); FloatToStr(SomeFloat, FormatSettings); end; |
Allerdings sind durch die Datenbankanbindung des Projekts zahllose Variantkonvertierungen vorhanden, die ich nicht manuell alle durchführen möchte! ;-)
Grüße
Hidden - Mo 13.10.08 13:04
Biergeneral hat folgendes geschrieben : |
| Allerdings sind durch die Datenbankanbindung des Projekts zahllose Variantkonvertierungen vorhanden, die ich nicht manuell alle durchführen möchte! ;-) |
Schreib' dir doch eine Methode MyStrToFloat wie oben beschrieben. Der Aufruf ist dann auch nicht aufwendiger als der von StrToFloat ;)
jaenicke - Mo 13.10.08 13:05
Er meint die automatischen Umwandlungen der Variants, wenn ich das richtig verstanden habe ;-).
Hidden - Mo 13.10.08 13:06
:oops: Ich hab' gelesen "Variantenkonvertierungen" :lol:
Biergeneral - Mo 13.10.08 23:09
Ja richtig ;-)
Ich meinte die zum einen die automatische konvertierung von OleVarients und den TVariants ;)
Klar - ich kann mir die Mühe machen an allen Stellen wo ich z.B. ein
Delphi-Quelltext
1:
| AdoQuery.Fields[0].AsString |
nutze vorher zu Prüfen ob der Wert NULL ist, obs ein gültiger Float ist etc.. oder ich überlass das (sicherlich auch aus Bequemlichkeit) den eingebauten Funktionen ;)
Ich fang jetzt die WM_WININICHANGE Message ab und ändere dann meine lokalen Einstellungen - falls sich an den locale_settings tatsächlich mal was geändert hat.. ( Auch wenn das eher zu den Seltenheiten gehören sollte ;-) )
Grüße und Danke nochmal
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!