Delphi-PRAXiS

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!!

Bernhard Geyer 10. Apr 2007 17:07

Re: Delphi <= 7 Unicode Conversion Bug
 
Liste der Anhänge anzeigen (Anzahl: 2)
Der Knoten liegt bei dir (bzw. deinem Windows). Ich habe keine Probleme.

Die PNG-Datei zeigt eine Bildschirmkopie. Das obere Edit ist ein TEdit, das Untere Edit ein TElEdit.
Die automatische Konvertierung String -> Widestring zeigt keine Probleme.

Angehängt ist auch die Testexe + Sourcen

ulrich.b 10. Apr 2007 17:43

Re: Delphi <= 7 Unicode Conversion Bug
 
Liste der Anhänge anzeigen (Anzahl: 2)
Also danke erstmal, dass du es auch versucht hast .... :thumb:

Nur ist mir jetzt alles noch unklarer! :)

Wie du im Anhang siehst, funktioniert auch in meinem System (Win 2003 in VMWare) die Umwandlung korrekt. Im Unteren Edit ist der "öäü", String, da es anscheinend ein Unicode Control ist, und meine Eingaben auf der deutschen Tastatur korrekt wiedergibt. Wie es ja auch sein sollte.

Auf dem SELBEN System ist implizite Conversion von meinem Programm (Code attached) aber Falsch!

Die einzige Erklärung für mich ist im Moment, dass deine Unicode Controls (dieses ELEdit) den Delphi Bug irgendwie beheben (wie es ja auch die Tnt Controls machen). Welche Komponenten sind das eigentlich?

Könntest du noch kurz das selbe Programm übersetzen, ohne diese Komponenten (alle uses Einträge entfernen)? Wär echt toll!

EDIT:
Welche Delphi Version hast du eigentlich verwendet?

Bernhard Geyer 10. Apr 2007 19:56

Re: Delphi <= 7 Unicode Conversion Bug
 
Zitat:

Zitat von ulrich.b
Auf dem SELBEN System ist implizite Conversion von meinem Programm (Code attached) aber Falsch!

Kann ich erst morgen kontrollieren

Zitat:

Zitat von ulrich.b
Die einzige Erklärung für mich ist im Moment, dass deine Unicode Controls (dieses ELEdit) den Delphi Bug irgendwie beheben (wie es ja auch die Tnt Controls machen). Welche Komponenten sind das eigentlich?

Diese Controls sind Unicode-Controls. Sprich sie haben selbst das Windows-Handling implementiert und arbeiten nur mit Widestrings (auch unter Win9x/ME Unicode in der GUI möglich

Zitat:

Zitat von ulrich.b
Könntest du noch kurz das selbe Programm übersetzen, ohne diese Komponenten (alle uses Einträge entfernen)? Wär echt toll!

Morgen

Zitat:

Zitat von ulrich.b
Welche Delphi Version hast du eigentlich verwendet?

Delphi 6 Pro


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:28 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