Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Decimalseparator... WinXP vs. Win7??? (https://www.delphipraxis.net/160539-decimalseparator-winxp-vs-win7.html)

haraldr 18. Mai 2011 14:48

Decimalseparator... WinXP vs. Win7???
 
Werden Gleitkommawerte in WindowsXP und Windows7 in Delphi Programmen unterschiedlich interpretiert?

Auch wenn es hier schon ähnliche Threads gibt, möchte ich ein Problem schildern, das mir gerade auf die Füße gefallen ist.

Ich verwende bisher für die Aus- und Eingabe von Gleitkommadaten die einfachen Formatierungsfunktionen z.B. Format('%8.2f',[gkzahl]) oder FloatToStr(gkzahl) bzw. StrToFloat('0,75'). Da die Ländereinstellungen alle auf "Deutsch" stehen und dort das Komma als Decimalseparator eingetragen ist, funktionierte das bisher (alle PC's in unserer Firma hatten WinXP) ohne Probleme.

Seit Win7 kommt die Software nicht mehr mit dem "Komma" als Decimalseparator klar.
Kleines Beispiel:
Delphi-Quellcode:
  GetLocaleFormatSettings(GetSystemDefaultLCID, FSettings);
  Edit1.Text:=FSettings.DecimalSeparator;
  Edit2.Text:=FSettings.ThousandSeparator;
liefert sowohl unter WinXP als auch unter Win7 erwartungsgemäß in den Edit-Feldern für Decimalseparator das Komma und für ThousandSeparator den Punkt.
Delphi-Quellcode:
  x:=3;
  y:=4;
  z:=x/y;
  Edit3.Text:=Format('%8.2f',[z]);
zeigt mir unter WinXP als Ergebnis 0,75 (Null Komma 75) an.
Unter Win7 steht in dem Editfeld 0.75 (Null Punkt 75).

Die offensichtliche Lösung in diesem Fall ist, überall Ausgaben der Form
Delphi-Quellcode:
  Edit3.Text:=Format('%8.2f',[z],fsettings);
zu verwenden. (Das würde bei der von mir in den letzten ca. 20 Jahren geschriebenen Software höchstens 10000 Zeilen verteilt auf vielleicht 1000 Quelltextfiles betreffen, wäre also prinzipell machbar.8-))

Nun meine Frage: Ein ähnliches Problem habe ich mit der Abfrage von Datenbankfeldern.
Unter WinXP haben Abfragen der Art:
Delphi-Quellcode:
  gkwert:=Tabelle.FieldByName('Feldname').AsFloat;
immer funktioniert, auch wenn implizit Typumwandlungen notwendig waren (wenn z.B. das Tabellenfeld als Text vereinbart war).
Unter Win7 kommt es an dieser Stelle zum Konvertierungsfehler (0,75 ist kein Gleitkommawert)

Gibt es eine Lösung, dieser "AsFloat"-Funktion auch die FormatSettings mitzuteilen oder muss ich mir mit einem Konstrukt wie:
Delphi-Quellcode:
  zkwert:=Tabelle.FieldByName('Feldname').AsString;
  gkwert:=StrToFloat(zkwert, fsettings);
helfen???:cry:

Generell würde mich interessieren, woher meine Anwendung im Falle, dass ich nicht die "threadsicheren" Funktionsaufrufe mit expliziter FormatSettings-Übergabe verwende, diese Informationen hernimmt.:?:

Herzliche Grüße
Harald

himitsu 18. Mai 2011 14:53

AW: Decimalseparator... WinXP vs. Win7???
 
Es gibt in "einigen" Win7-Intallationen ein Problem mit der Spracheinstellung.

Geh mal in Systemsteuerung > Region und Spachen > Format und stell dort das Format auf was anderes ein (z.B. Englisch [USA]) und dann zurück auf Deutsch.

Ist der Fehler dann immernoch da?

rollstuhlfahrer 18. Mai 2011 14:55

AW: Decimalseparator... WinXP vs. Win7???
 
In der Unit System oder SysUtils gibt es ein paar Variablen. Diese heißen unter anderem "ThousandsSeperator" oder "DecimalSeperator". Diese verwendet Delphi beim Nicht-Threadsicheren aufruf.

Für dein anderes Problem gibt es aber eine Lösung: Win7 sagen, dass er auf "Englisch" (Regionseinstellungen, nicht die Sprache) umzustellen hat und dann wieder auf "Deutsch". Danach sollte Win7 akzeptieren, dass der Dezimaltrenner ein Komma ist. Das Problem ist bekannt (nur weiß ich nicht, ob MS das auch weis).

Bernhard

haraldr 18. Mai 2011 16:42

AW: Decimalseparator... WinXP vs. Win7???
 
Zunächst vielen Dank für die Antworten.

Ausprobieren kann ich es erst morgen, wenn ich wieder die Gelegenheit habe, auf Win7 zu testen. Wir haben noch überwiegend WinXP im Einsatz.:wink:

Harald

haraldr 19. Mai 2011 07:07

AW: Decimalseparator... WinXP vs. Win7???
 
So...

Es war eine schwere Geburt.

Ich habe die formatierte Darstellung von Zahlenwerten auf 2 Versionen von Windows 7 ausprobiert.

Die Starter-Version verhält sich wie WindowsXP, dort werden also die Ländereinstellungen des Systems ohne Murren von meiner in Delphi erstellten Software erkannt.

Unter Windows 7 Professional 64bit könnte die Antwort auf den Lösungsvorschlag mit der temporären Umstellung der Ländereinstellungen von Radio Jerewan stammen: Im Prinzip schon...:lol:

Da ich zunächst als normaler Benutzer zugange war, brachte die Änderung der Ländereinstellungen keine Besserung. Seltsamerweise zeigte auch mein in Delphi erstelltes Tool trotz English(USA) weiterhin das Komma als Decimalseparator an.
Delphi-Quellcode:
  GetLocaleFormatSettings(GetSystemDefaultLCID, FSettings);
  Edit1.Text:=FSettings.DecimalSeparator;
Als Administrator angemeldet funktionierte der vorgeschlagene Workaround auf Anhieb.
Neuer Reboot... Anmeldung als normaler Benutzer... gleiches Problem.:evil:

Erst nachdem ich sämtliche Kombinationen aus Administrator/normaler Benutzer, mit und ohne zwischenzeitliche Reboots durchprobiert hatte, funktionierte plötzlich die Darstellung bzw. das Erkennen des korrekten (deutschen) Zahlenformats... Auch nach einem kompletten Neustart des Systems und Anmeldung als normaler Benutzer.

Dem Endanwender ist eine solche Vorgehensweise vermutlich nicht vermittelbar.:(
... und ich kann leider nicht reproduzierbar nachvollziehen, welche Wechsel der Ländereinstellungen unter welchem Benutzeraccount ich ausgeführt habe, bevor mir die gewünschten Einstellungen gelungen sind.

Trotzdem mochmals vielen Dank für den Tipp.

Harald

user0815 19. Mai 2011 08:04

AW: Decimalseparator... WinXP vs. Win7???
 
Hier ist das ganze gut beschrieben: http://www.delphipraxis.net/156447-d...lsettings.html

Delphi-Quellcode:
uses Registry;

{$R *.dfm}

function Win7LocaleCheck : String;
var
  regist : TRegistry;
  s : String;
begin
  s := '';
  regist := TRegistry.create();
  try
    regist.RootKey := HKEY_CURRENT_USER;
    if regist.Openkey('\Control Panel\International', false) then
    begin
      s := 'Locale: ' + regist.ReadString('Locale');
      s := s + '/ LocaleName:' +regist.ReadString('LocaleName');
    end;
    regist.CloseKey;
  finally
    regist.Free;
  end;

  Result := s;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage(Win7LocaleCheck);
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:17 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz