![]() |
GetLocaleInfo() Aufruf, ist es so richtig?
Hallo, ich würde mich gerne absichern ob folgender Code korrekt ist:
Delphi-Quellcode:
Ziel soll sein das ich in einem String das/die Zeichen für's Lokale Tausender-Trennzeichen bekomme.
function ThousandSeparator : String;
var buf: PChar; // temp puffer begin Result := '#'; // falsch initialisieren, gegebenfalls später mit einem Default-Wert bei Fehler ersetzen try buf := StrAlloc(10); // puffer eine größe zusichern GetLocaleInfo( LOCALE_SYSTEM_DEFAULT, LOCALE_STHOUSAND, buf, 10); // GetLocaleInfo() direkt abfragen ohne die Länge vom Trennzeichen zu kennen, aber über 10 sollten es wohl nicht werden finally Result := StrPas(buf); // in einen String konvertieren StrDispose(buf); // speicher bereinigen end; end; Oder ist es generell so falsch und es gibt aktuellere Methoden um das Zeichen (als String) zu bekommen? |
AW: GetLocaleInfo() Aufruf, ist es so richtig?
Zitat:
![]() Ansonsten noch zum WinAPI Ansatz: "Theoretisch" kann
Delphi-Quellcode:
fehlschlagen. In diesem Falle läuft dein
StrAlloc
Delphi-Quellcode:
im
StrDispose
Delphi-Quellcode:
Block ins Leere. Und die fixe Länge von 10 wird sicherlich auch funktionieren, aber korrekter wäre es die API einmal mit
finally
Delphi-Quellcode:
Buffer und 0 Länge aufzurufen und den Rückgabewert zu verwenden. Alternativ einen fixen Anfangsbuffer, Rückgabe prüfen,
nil
![]()
Delphi-Quellcode:
prüfen, Buffer verdoppeln, Aufruf wiederholen, etc.
ERROR_INSUFFICENT_BUFFER
|
AW: GetLocaleInfo() Aufruf, ist es so richtig?
Wäre es so korrekt? (mit Verzicht auf WinApi)
Delphi-Quellcode:
Muss ich da noch Speicher bereinigen?
function ThousandSeparator : String;
var FS: TFormatSettings; begin FS := TFormatSettings.Create; Result := FS.ThousandSeparator; end; |
AW: GetLocaleInfo() Aufruf, ist es so richtig?
Zitat:
Delphi-Quellcode:
. Alternativ beinhaltet
record
Delphi-Quellcode:
auch die globale Variable
System.SysUtils
Delphi-Quellcode:
, die du direkt verwenden kannst.
FormatSettings
|
AW: GetLocaleInfo() Aufruf, ist es so richtig?
Zitat:
|
AW: GetLocaleInfo() Aufruf, ist es so richtig?
Nun aber hoffentlich Ok:
Delphi-Quellcode:
Vielen Dank für so schnelle Hilfe!
function ThousandSeparator : String;
begin Result := FormatSettings.ThousandSeparator; end; |
AW: GetLocaleInfo() Aufruf, ist es so richtig?
Jetzt noch alles in eine eigene Unit und alles ist sauber, schön und leicht erweiterbar (jedenfalls würde ich es so machen).
Delphi-Quellcode:
So eine ähnliche Unit habe ich. Grund für MyFormatSettings ist, weil ich FormatSettings überschreibe und immer noch die originalen Werte haben möchte.
unit MyUnitX;
interface type TUnitX = record private var MyFormatSettings: TFormatSettings; public class function ThousandSeparator : string; static; end; implementation var UnitX: TUnitX; class function TUnitX.ThousandSeparator : String; begin Result := FormatSettings.ThousandSeparator; end; initialization UnitX.MyFormatSettings := TFormatSettings.Create(GetUserDefaultLCID); |
AW: GetLocaleInfo() Aufruf, ist es so richtig?
Ich portiere gerade Code der auf System.ThousandSeperator aufbaute, kommt nur in einer Unit vor, hab da nun meine funktion drinn, klappte auch beim ersten Post, ich wollte mich nur absichern das ich da kein Fehler mache, da ich die WinApi Antwort leider nicht ganz Verstanden habe erschien mir das was ich Verstanden habe einfacher umzusetzen. :mrgreen:
[EDIT]Also das mit dem StrDispose() das es fehlschlagen könnte hab ich Verstanden aber den Rest noch nicht.[/EDIT] |
AW: GetLocaleInfo() Aufruf, ist es so richtig?
Zitat:
Delphi-Quellcode:
gehört vor das TRY
buf := StrAlloc(10); // puffer eine größe zusichern
und
Delphi-Quellcode:
gehört vor Finally oder hinter das End.
Result := StrPas(buf);
Falls StrAlloc knallt, führst du dennoch StrDispose aus, es knallt nochmal und verfälscht den eigentlichen Fehler und wenn es knallt, greifst du auch noch auf buf zu, was ebenfalls nicht gut ist. UND, diese API löst keine Exceptions aus, also hilft Try-Finally/Except garnichts. Und falls es doch knallt, dann hattest DU "buf" falsch/nicht initialisiert oder es ist so viel kaputt, dass eine Fehlerbehandlung eh sinnlos ist. (ist = war vorher schon) Zitat:
PS: Wenn ich Code als "Delphi/Pascal" implementiere, dann lasse ich das C-typische StrAlloc weg und nutzte einen passenden Delphi-String (AnsiString/UnicodeString/String) und das StrDispose macht Delphi für mich. Nach der API mit SetLength oder einem billigen PChar-Cast den String kürzen, falls der Inhalt doch kleiner war. Oder ich nutze ein statisches Char-Array und ![]() |
AW: GetLocaleInfo() Aufruf, ist es so richtig?
So war mein Ansatz nach Zacherl's erstem Post:
Delphi-Quellcode:
function ThousandSeparator : String;
var buf: PChar; begin Result := ','; // falls was schiefläuft einen default Wert buf := StrAlloc(10); if GetLastError() = ERROR_SUCCESS then if GetLocaleInfo( LOCALE_SYSTEM_DEFAULT, LOCALE_STHOUSAND, buf, 10) <> 0 then Result := StrPas(buf); if GetLastError() <> ERROR_INSUFFICIENT_BUFFER then StrDispose(buf); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:41 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz