Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Delphi <= 7 Unicode Conversion Bug (https://www.delphipraxis.net/89785-delphi-%3D-7-unicode-conversion-bug.html)

ulrich.b 5. Apr 2007 17:21


Delphi <= 7 Unicode Conversion Bug
 
Wenn ich in Delphi 7 und vorher einen String in einen WideString konvertiere macht (so weit ich das sehe) Delphi nichts anderes, als das String Byte in das Lo-Byte des WideString Characters zu kopieren, und nicht das Zeichen, abhängig vonm der aktuellen System Charset Einstellung richtig zu konvertieren!!!


Z.B.:
Das "ö" hat in der Westlichen Codepage den Code 0xF6
In der griechischen CodePage ist 0xF6 aber ein kleines Phi "φ"

Wenn ich nun ein 0xF6 in ein Unicode Zeichen konvertieren will sollte es eigentlich abhängig von der Systen Codepage in ein Unicode Zeichen konvertiert werden. Was passiert ist aber, dass es immer in ein 0x00F6 konvertiert wird (ist in diesem Fall zufälligerweise das kleine "ö") ...

Wie kann ich dieses Verhalten von Delphi fixen (es ist ja eine Function in der System Unit)?

Bernhard Geyer 5. Apr 2007 17:47

Re: Delphi <= 7 Unicode Conversion Bug
 
Das kann ich so nicht nachvollziehen (D6) bzw. versteh es nicht ganz.
Zeit mal genau den Code den du verwendest!

shmia 5. Apr 2007 17:54

Re: Delphi <= 7 Unicode Conversion Bug
 
In der Unit System gibt es folgende Funktion
Delphi-Quellcode:
function StringToWideChar(const Source: string; Dest: PWideChar;
  DestSize: Integer): PWideChar;
begin
  Dest[MultiByteToWideChar(0 {=CP_ACP}, 0, PChar(Source), Length(Source),
    Dest, DestSize - 1)] := #0;
  Result := Dest;
end;
Der Parameter CP_ACP bedeutet "ANSI code page".
Ich vermute nun, dass Delphi obige Funktion verwendet und damit immer die ANSI Code Page als Ausgangspunkt nimmt.
Welchen Wert liefert denn die Funktion GetACP() auf deinem (grichischen) System ?

Bernhard Geyer 5. Apr 2007 21:20

Re: Delphi <= 7 Unicode Conversion Bug
 
Es könnte je nachdem wie es im Code definiert ist einfach die Tatsache zuschalgen das Delphi-Pas-Dateien bei Delphi > Version 8 immer Ansi-Textdateien sind und deshalb beim Compilieren mit der aktuellen Codepage umgesetzt werden müssen.

ulrich.b 9. Apr 2007 15:49

Re: Delphi <= 7 Unicode Conversion Bug
 
Liste der Anhänge anzeigen (Anzahl: 2)
Zitat:

Zitat von Bernhard Geyer
Das kann ich so nicht nachvollziehen (D6) bzw. versteh es nicht ganz.

Da da jemand ungläubig ist, hab ich 2 Screenshots gemacht. Ein Screenshot auf einem System mit deutscher Codepage und einen mit griechischer. Man sieht, dass bei der Umwandlung in den WideString beide Male das selbe Ergebnis rauskommt, obwohl verschiedene Zeichen umgewandelt werden.


Eben der Bug, den ich oben beschrieben habe!!!

Delphi-Quellcode:
procedure TForm1.Edit1Change(Sender: TObject);
var
  Str    : String;
  WStr   : WideString;

  WStrLen : Integer;

  HexStr : String;

  i      : Cardinal;

  p      : Pointer;

  ByteVal : Byte;

begin
  Str := Edit1.Text;

  WStr := Str;


  WStrLen := Length(WStr);

  p := @WStr[1];

  HexStr := '';

  for i := 0 to WStrLen * 2 do
  begin
    ByteVal := PByte((Cardinal(p) + i))^;

    HexStr := HexStr + IntToHex(ByteVal, 2);
  end;

  Label1.Caption := HexStr;
end;

Bernhard Geyer 9. Apr 2007 18:46

Re: Delphi <= 7 Unicode Conversion Bug
 
Hast Du evtl. die TNT's installiert und dort die "Fixes" für die Systemroutinene installiert/aktiviert?

shmia 10. Apr 2007 09:25

Re: Delphi <= 7 Unicode Conversion Bug
 
Zitat:

Zitat von ulrich.b
Ein Screenshot auf einem System mit deutscher Codepage und einen mit griechischer. Man sieht, dass bei der Umwandlung in den WideString beide Male das selbe Ergebnis rauskommt, obwohl verschiedene Zeichen umgewandelt werden.

Die VCL/RTL kann nicht wissen, welche Codepage du verwendet hast!!
Die Funktion GetACP() liefert die default Codepage deiner Windows-Installation.
Wenn die Codepage des TFont-Objekts davon abweicht, musst du die Zeichenkonvertierung selbst vornehmen.
Delphi-Quellcode:
function StringToWideCharEx(const Source: string;SourceCP:integer; Dest: PWideChar;
  DestSize: Integer): PWideChar;
begin
  Dest[MultiByteToWideChar(SourceCP, 0, PChar(Source), Length(Source),
    Dest, DestSize - 1)] := #0;
  Result := Dest;
end;


begin
  Str := Edit1.Text;
//  WStr := Str;
  // ungetestet
  SetLength(WStr, Length(Str));
  StringToWideCharEx(Str, Edit1.Font.Charset, @Wstr[1], Length(Str)*2);

ulrich.b 10. Apr 2007 15:03

Re: Delphi <= 7 Unicode Conversion Bug
 
Zitat:

Zitat von Bernhard Geyer
Hast Du evtl. die TNT's installiert und dort die "Fixes" für die Systemroutinene installiert/aktiviert?

NEEEEEEIN! Ich hab sie eben NICHT installiert. Mit den FIXES geht das alles auch in Delphi 7. OHNE Ihnen ja auch in Delphi >= 2005! Trotzdem will ich es in Delphi 7 hinbekommen!

Zitat:

Zitat von shmia
Die VCL/RTL kann nicht wissen, welche Codepage du verwendet hast!!
Die Funktion GetACP() liefert die default Codepage deiner Windows-Installation.
Wenn die Codepage des TFont-Objekts davon abweicht, musst du die Zeichenkonvertierung selbst vornehmen.

Ja genau desshalb sprech ich ja von einem Delphi BUG! Es sollte doch die System CodePage ausgelesen werden und danach, abhängig von dieser, die Umwandlung passieren!

... Natürlich weiß ich, dass ich die "MultiByteToWideChar" Funktion selbst benutzen kann, nur will ich keinesfalls in einem doch relativ umfangreichen (vor allem Strigverarbeitungsintensiven) Projekt nicht auf die Implizite String zu WideString Umwandlung verzichten!!!

LG Ulrich

Bernhard Geyer 10. Apr 2007 15:25

Re: Delphi <= 7 Unicode Conversion Bug
 
Gibt mal ein Beispielprojekt rüber mit der genauen Anleitung was wann passiert.
Irgendwie ist bei uns oder bei dir noch irgendwo ein Knoten im Gehirn.

ulrich.b 10. Apr 2007 16:16

Re: Delphi <= 7 Unicode Conversion Bug
 
Zitat:

Zitat von Bernhard Geyer
Gibt mal ein Beispielprojekt rüber mit der genauen Anleitung was wann passiert.
Irgendwie ist bei uns oder bei dir noch irgendwo ein Knoten im Gehirn.

Bitte nimm dir kurz mal Zeit, um meinen oben geposteten Code auszuführen, ...

Stell in Windows einmal auf z.B. deutsch oder englisch und ein zweites mal auf griechisch (Zu finden unter den "Region/Spracheinstellungen" auf der "Erweitert" - Page, ... reboot erforderlich)

... dann starte das Programm und gib "ö" auf deiner deutschen Tastatur ein!

Beides Male wandelt Delphi/mein Code das "ö" in ein F600 (little endian, was einem 0x00F6 entspricht).

Und .... jetzt kommts ...

Es sollten doch 2 verschiedene Zeichen rauskommen!

Genauer: bei Englischer Einstellung: 0x00F6 (kleines ö) und bei griechisch 0x03C6 (kleines phi).

... Oder sehe ich da irgend etwas falsch?

EDIT:
Der Bug den ich meine, ist wahrscheinlich genau der, der von den TNT Controls, die es ja jetzt nicht mehr gibt, extern gefixt wird!!


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:10 Uhr.
Seite 1 von 2  1 2      

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