AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi GetLocaleInfo() Aufruf, ist es so richtig?
Thema durchsuchen
Ansicht
Themen-Optionen

GetLocaleInfo() Aufruf, ist es so richtig?

Ein Thema von KodeZwerg · begonnen am 2. Apr 2018 · letzter Beitrag vom 3. Apr 2018
Antwort Antwort
Seite 1 von 3  1 23      
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#1

GetLocaleInfo() Aufruf, ist es so richtig?

  Alt 2. Apr 2018, 17:33
Hallo, ich würde mich gerne absichern ob folgender Code korrekt ist:

Delphi-Quellcode:
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;
Ziel soll sein das ich in einem String das/die Zeichen für's Lokale Tausender-Trennzeichen bekomme.
Oder ist es generell so falsch und es gibt aktuellere Methoden um das Zeichen (als String) zu bekommen?
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#2

AW: GetLocaleInfo() Aufruf, ist es so richtig?

  Alt 2. Apr 2018, 17:38
Oder ist es generell so falsch und es gibt aktuellere Methoden um das Zeichen (als String) zu bekommen?
Delphi hat diese Schnittstelle gekapstelt:
http://docwiki.embarcadero.com/CodeE...ttings_(Delphi)

Ansonsten noch zum WinAPI Ansatz:
"Theoretisch" kann StrAlloc fehlschlagen. In diesem Falle läuft dein StrDispose im finally Block ins Leere. Und die fixe Länge von 10 wird sicherlich auch funktionieren, aber korrekter wäre es die API einmal mit nil Buffer und 0 Länge aufzurufen und den Rückgabewert zu verwenden. Alternativ einen fixen Anfangsbuffer, Rückgabe prüfen, MSDN-Library durchsuchenGetLastError auf ERROR_INSUFFICENT_BUFFER prüfen, Buffer verdoppeln, Aufruf wiederholen, etc.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)

Geändert von Zacherl ( 2. Apr 2018 um 17:41 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: GetLocaleInfo() Aufruf, ist es so richtig?

  Alt 2. Apr 2018, 18:09
Wäre es so korrekt? (mit Verzicht auf WinApi)

Delphi-Quellcode:
function ThousandSeparator : String;
var
  FS: TFormatSettings;
begin
  FS := TFormatSettings.Create;
  Result := FS.ThousandSeparator;
end;
Muss ich da noch Speicher bereinigen?
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#4

AW: GetLocaleInfo() Aufruf, ist es so richtig?

  Alt 2. Apr 2018, 18:14
Muss ich da noch Speicher bereinigen?
Nee, ist ja ein record . Alternativ beinhaltet System.SysUtils auch die globale Variable FormatSettings , die du direkt verwenden kannst.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
günni0
(Gast)

n/a Beiträge
 
#5

AW: GetLocaleInfo() Aufruf, ist es so richtig?

  Alt 2. Apr 2018, 18:15
Wäre es so korrekt? (mit Verzicht auf WinApi)

Delphi-Quellcode:
function ThousandSeparator : String;
var
  FS: TFormatSettings;
begin
  FS := TFormatSettings.Create;
  Result := FS.ThousandSeparator;
end;
Muss ich da noch Speicher bereinigen?
So ungefähr mache ich es auch. Bisher hat sich, trotz internationalem Gebrauch meines Programms, keiner beschwert. Ich erstelle TFormatSettings aber nur einmalig bei Programmstart und nutze die so gewonnenen Daten dann weiter.
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: GetLocaleInfo() Aufruf, ist es so richtig?

  Alt 2. Apr 2018, 18:33
Nun aber hoffentlich Ok:

Delphi-Quellcode:
function ThousandSeparator : String;
begin
  Result := FormatSettings.ThousandSeparator;
end;
Vielen Dank für so schnelle Hilfe!
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
günni0
(Gast)

n/a Beiträge
 
#7

AW: GetLocaleInfo() Aufruf, ist es so richtig?

  Alt 2. Apr 2018, 18:34
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:
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);
So eine ähnliche Unit habe ich. Grund für MyFormatSettings ist, weil ich FormatSettings überschreibe und immer noch die originalen Werte haben möchte.

Geändert von günni0 ( 2. Apr 2018 um 18:40 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: GetLocaleInfo() Aufruf, ist es so richtig?

  Alt 2. Apr 2018, 18:41
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.
[EDIT]Also das mit dem StrDispose() das es fehlschlagen könnte hab ich Verstanden aber den Rest noch nicht.[/EDIT]
Gruß vom KodeZwerg

Geändert von KodeZwerg ( 2. Apr 2018 um 18:49 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.051 Beiträge
 
Delphi 12 Athens
 
#9

AW: GetLocaleInfo() Aufruf, ist es so richtig?

  Alt 2. Apr 2018, 18:51
Hallo, ich würde mich gerne absichern ob folgender Code korrekt ist
...
Oder ist es generell so falsch und es gibt aktuellere Methoden um das Zeichen (als String) zu bekommen?
Gegenfrage: Warum hörst du nicht auf deinen Compiler? (vonwegen Variable nicht initialisiert)

buf := StrAlloc(10); // puffer eine größe zusichern gehört vor das TRY
und Result := StrPas(buf); gehört vor Finally oder hinter das End.

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:
falsch initialisieren, gegebenfalls später mit einem Default-Wert bei Fehler ersetzen
Und wie willst du erkennen, ob es einen Fehler gab, wenn du das Result dieser API nicht auswertest?


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 Delphi-Referenz durchsuchenSetString
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu ( 2. Apr 2018 um 19:39 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#10

AW: GetLocaleInfo() Aufruf, ist es so richtig?

  Alt 2. Apr 2018, 19:17
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;
Gruß vom KodeZwerg

Geändert von KodeZwerg ( 2. Apr 2018 um 19:22 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:22 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