Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi XE2: Probleme mit Umwandlung von Char zu Byte (https://www.delphipraxis.net/165934-xe2-probleme-mit-umwandlung-von-char-zu-byte.html)

Helmi 22. Jan 2012 19:30


XE2: Probleme mit Umwandlung von Char zu Byte
 
Hallo,

ich kämpf gerade mit dem Portieren eines in Delphi7-geschriebenen Projektes in Delphi XE2.
Darin beschreib ich ein LCD-Modul.

Blöderweise kann ich Texte nicht 1:1 an das Modul senden, da einige Sonderzeichen einen anderen Hexwert haben.

Dazu hab ich mir damals folgendes Konstrukt gebaut:

Delphi-Quellcode:
procedure TMainForm.LCD_Text_senden(Text: String; Zeilenumbruch: Boolean = false;
  leeren: Boolean = false; Schritt: Boolean = false; Verzoegerung: Word = 100);
const
  Chars: array[1..10] of Char = ('ä', 'ö', 'ü', 'Ä', 'Ö', 'Ü', 'ß', '²', '³', 'µ');
  Bytes: array[1..10] of Byte = ($84, $94, $81, $8E, $99, $9A, $E1, $FD, $FE, $E6);

var
  i              : Integer;
  Pos_char       : Integer;

begin
  {...}

  //Sonderzeichen auslesen
  for i := 1 to length(Text) do
    begin
      //prüfen ob Char im Array "Chars" ist
      Pos_Char := Pos((Text[i]), Chars);

      //Sonderzeichen vorhanden? - dann durch Byte-Wert ersetzen
      If Pos_Char > 0 then
        Text[i] := Chr(Bytes[Pos_Char]);
    end;

  {...}
end;
Unter Delphi7 hats bestens funktioniert. Unter XE2 leider nein, da die ersetzten Werte z. B. bei "ä" nicht mehr $84, sondern $0084 und damit hat das LCD-Modul Probleme.

Nun könnt ich aus
Delphi-Quellcode:
Text: String
einfach
Delphi-Quellcode:
Text: AnsiString
machen.

Aber wie müsst es denn mit String gemacht werden? (falls das überhaupt mit String geht)

Dummerweise bekomm ich dann bei anderen Codezeilen (z. b. wo Insert verwendet wird) dann Warnungen (z. B. [DCC Warnung] Unit1.pas(208): W1058 Implizite String-Umwandlung mit potenziellem Datenverlust von 'string' zu 'AnsiString').

Ich würd halt gerne das Ganze auf
Delphi-Quellcode:
Text: String
lassen.

jaenicke 22. Jan 2012 19:45

AW: Xe2: Probleme mit Umwandlung von Char zu Byte
 
Wenn du an dein LCD-Modul einen AnsiString schicken musst, kannst du logischerweise auch nicht mit String als Variablentyp arbeiten.

Für mich sieht das so aus, dass du schlicht statt Bytefummelei überall AnsiChar und statt string AnsiString nehmen muss. Natürlich kannst du auch eine lokale AnsiString Variable nehmen und da den übergebenen Wert reinlegen, damit du nach außen direkt UnicodeStrings akzeptieren kannst.

Pos würde ich nicht benutzen, da du dann wieder bei Unicode wärst. Scheue dich doch nicht eine Schleife zu benutzen wo es sinnvoll ist. Hier macht Pos nicht wirklich Sinn. Und mit AnsiChar kannst du dir auch die ganzen Casts sparen.
Delphi-Quellcode:
procedure TMainForm.LCD_Text_senden(Text: String; Zeilenumbruch: Boolean = false;
  leeren: Boolean = false; Schritt: Boolean = false; Verzoegerung: Word = 100);
const
  Chars: array[1..10] of AnsiChar = ('ä', 'ö', 'ü', 'Ä', 'Ö', 'Ü', 'ß', '²', '³', 'µ');
  ReplacementChars: array[1..10] of AnsiChar = (#$84, #$94, #$81, #$8E, #$99, #$9A, #$E1, #$FD, #$FE, #$E6);
var
  i, j: Integer;
  AnsiText: AnsiString;
begin
  {...}

  AnsiText := AnsiString(Text);
  //Sonderzeichen auslesen
  for i := 1 to Length(Text) do
    for j := Low(Chars) to High(Chars) do
      if AnsiText[i] = Chars[j] then
        AnsiText[i] := ReplacementChars[j];

  {...}
end;
So ist der Code kürzer, übersichtlicher und Warnungen sollte es auch nicht mehr geben.

Nebenbei:
Deine Variablen solltest du besser ordentlich bezeichnen. Die Bezeichnung Text gibt es in Delphi z.B. schon... Besser sind eindeutige Bezeichner.

Helmi 22. Jan 2012 19:51

AW: Xe2: Probleme mit Umwandlung von Char zu Byte
 
Die Idee das mit einer 2. Schleife zu machen, klingt ganz gut.
Einen normalen String zu schicken ist kein Problem - wird vom Modul sauber erkannt und angezeigt.
Nur eben diese Sonderzeichen machen Probleme.

Die Bezeichner bleiben so wie sie sind und haben auch ihren Sinn. Ich weiss das Text auch bei Delphi verwendet wird.
Aber das hindert nicht daran dass man diese auch selbst verwenden kann/darf. Wenn es Sinn macht dann nutz ich diese.

Bernhard Geyer 22. Jan 2012 20:01

AW: Xe2: Probleme mit Umwandlung von Char zu Byte
 
Zitat:

Zitat von Helmi (Beitrag 1147146)
Aber wie müsst es denn mit String gemacht werden? (falls das überhaupt mit String geht)

Kann den dein LCD-Modul Zeichen anderer Codepages darstellen? Evtl. kannst du deinem LCD-Modul ja in einen "Unicode"-Modus umstellen.

jaenicke 22. Jan 2012 20:04

AW: Xe2: Probleme mit Umwandlung von Char zu Byte
 
Als ich deine Bytewerte eben noch einmal angeschaut habe, ist mir aufgefallen, dass es noch sehr viel einfacher geht...
Delphi-Quellcode:
procedure TMainForm.LCD_Text_senden(Text: String; Zeilenumbruch: Boolean = false;
  leeren: Boolean = false; Schritt: Boolean = false; Verzoegerung: Word = 100);
var
  AnsiText: AnsiString;
begin
  {...}

  SetLength(AnsiText, Length(Text));
  if not CharToOem(PChar(Text), PAnsiChar(AnsiText)) then
    AnsiText := AnsiString(Text);

  {...}
// EDIT:
Zitat:

Zitat von Helmi (Beitrag 1147148)
Ich weiss das Text auch bei Delphi verwendet wird.
Aber das hindert nicht daran dass man diese auch selbst verwenden kann/darf. Wenn es Sinn macht dann nutz ich diese.

Da hast du Recht: Man kann und darf. Man sollte nur nicht. ;-)
Aber das ist ja deine Sache. Wenn du das erste Mal damit auf die Nase gefallen bist, siehst du es vielleicht anders. ;-)

Helmi 22. Jan 2012 20:05

AW: Xe2: Probleme mit Umwandlung von Char zu Byte
 
Zitat:

Zitat von Bernhard Geyer (Beitrag 1147149)
Zitat:

Zitat von Helmi (Beitrag 1147146)
Aber wie müsst es denn mit String gemacht werden? (falls das überhaupt mit String geht)

Kann den dein LCD-Modul Zeichen anderer Codepages darstellen? Evtl. kannst du deinem LCD-Modul ja in einen "Unicode"-Modus umstellen.

Leider nein - das wär zu einfach gewesen :-)

Helmi 22. Jan 2012 20:18

AW: Xe2: Probleme mit Umwandlung von Char zu Byte
 
Zitat:

Zitat von jaenicke (Beitrag 1147150)
Delphi-Quellcode:
SetLength(AnsiText, Length(Text));
  if not CharToOem(PChar(Text), PAnsiChar(AnsiText)) then
    AnsiText := AnsiString(Text);

Das wär zu schön um wahr zu sein - sehr schön kurz und so - nur leider passt es nicht ganz!
Z. B. wird "³" (hochgestellte 3) nicht richtig dargestellt)


Zitat:

Zitat von jaenicke (Beitrag 1147150)
Da hast du Recht: Man kann und darf. Man sollte nur nicht. ;-)
Aber das ist ja deine Sache. Wenn du das erste Mal damit auf die Nase gefallen bist, siehst du es vielleicht anders. ;-)

Also wo man mit solche Bezeichner auf die Schnauze fallen könnte (und ich auch schon bin) war in Verbindung mit "with".

Luckie 22. Jan 2012 20:47

AW: Xe2: Probleme mit Umwandlung von Char zu Byte
 
OK bei text mag es noch gehen. Bei Caption wird es aber schon kritisch, da auch ein Formular diese Eigenschaft hat. Und wenn du jetzt eine lokale Variable Caption nennst, weiß ich nicht,ob Delphi weiß, was gemeint ist. Und auch wenn es Delphi wissen sollte, würde es eher verwirren.

jaenicke 22. Jan 2012 20:48

AW: Xe2: Probleme mit Umwandlung von Char zu Byte
 
Zitat:

Zitat von Helmi (Beitrag 1147155)
Das wär zu schön um wahr zu sein - sehr schön kurz und so - nur leider passt es nicht ganz!
Z. B. wird "³" (hochgestellte 3) nicht richtig dargestellt)

Hmm, das ist auch das einzige Zeichen. Alles andere passt in die Codepage 850. Die hochgestellte 3 steht aber in keiner Codepage an der Stelle. Wenn alles andere korrekt dargestellt wird, könntest du dafür eine Ausnahme machen. Oder du bleibst bei der Arraylösung.
Aber wie sieht es mit den diversen anderen Sonderzeichen aus? Vielleicht würden diese mit CharToOem ansonsten alle schon funktionieren.

Zitat:

Zitat von Helmi (Beitrag 1147155)
Also wo man mit solche Bezeichner auf die Schnauze fallen könnte (und ich auch schon bin) war in Verbindung mit "with".

Benenne den Parameter Text einfach mal um. Normalerweise würdest du dann Kompilierfehler an den Verwendungsstellen bekommen. Da Text aber eine Eigenschaft des Formulars ist, funktioniert es einfach nur nicht mehr...

Anderes Problem: Refactoring
Delphi-Quellcode:
procedure TForm185.Test(Text: string);
begin
  ShowMessage(Text);
end;
Extrahiere einfach mal die Zeile in der Methode. Was kommt heraus? Richtig, das falsche...
Delphi-Quellcode:
procedure TForm185.Test(Text: string);
begin
  ExtractedMethod;
end;

procedure TForm185.ExtractedMethod;
begin
  ShowMessage(Text);
end;
Der extrahierte Code kompiliert aber leider aufgrund der Benennung...
Und nun bemerke den Fehler bei einem etwas komplexeren Code sofort...

// EDIT:
Zitat:

Zitat von Luckie (Beitrag 1147158)
OK bei text mag es noch gehen. Bei Caption wird es aber schon kritisch, da auch ein Formular diese Eigenschaft hat.

Ein Formular hat auch die Eigenschaft Text.

Helmi 22. Jan 2012 20:56

AW: Xe2: Probleme mit Umwandlung von Char zu Byte
 
Zitat:

Zitat von jaenicke (Beitrag 1147159)
Hmm, das ist auch das einzige Zeichen. Alles andere passt in die Codepage 850. Die hochgestellte 3 steht aber in keiner Codepage an der Stelle. Wenn alles andere korrekt dargestellt wird, könntest du dafür eine Ausnahme machen. Oder du bleibst bei der Arraylösung.
Aber wie sieht es mit den diversen anderen Sonderzeichen aus? Vielleicht würden diese mit CharToOem ansonsten alle schon funktionieren.

Also alle anderen Zeichen schauen gut aus - bis eben das eine.
Ich hab aber jetzt kein Problem damit das mit der Arraylösung zu machen

Wo schaust du bezüglich der Codepage nach?


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