AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Unicode Frage

Offene Frage von "wschrabi"
Ein Thema von hitzi · begonnen am 22. Dez 2004 · letzter Beitrag vom 23. Dez 2004
Antwort Antwort
Benutzerbild von hitzi
hitzi

Registriert seit: 2. Jan 2003
Ort: Eibau
768 Beiträge
 
Delphi 2010 Professional
 
#1

Unicode Frage

  Alt 22. Dez 2004, 14:48
Hallo,

aus einem String "0" wird ja wenn ich denn nach Unicode umwandele -> $#00 + "0" + $#00
Ich habe das jetzt immer in einer Schleife gemacht (Verzeichnisname -> Unicode)

Delphi-Quellcode:
result := '';
  if s <> 'then begin
    se := s;
    while length(se) > 0 do begin
      result := result + #$00 + se[1];
      se := copy(se, 2, length(se));
    end;
    result := result + #$00;
  end;
Jetzt habe ich aber bei einem User (Russischer Zeichensatz) ein Problem, dass er das Verzeichnis nicht findet. Mit großer Wahrscheinlichkeit ist mir hier die oben genannte Routine zum Verhängnis geworden.

Bei meinen folgenden Test bin ich auf das Problem gestoßen, dass ich ein Unicodezeichen nicht in ein Char umwandeln kann.

"0" ist ja $#00 + "0" - ein Unicodezeichen entspricht also zwei Chars. Mit der unten gezeigten Routine komm ich aber nur an ein Char. Im Beispiel "0" bekomme ich also nur das Zeichen "0" zurück anstatt $#00 + "0".

Delphi-Quellcode:
var Test,Test1:PWideChar;
    i : integer;
    sm : string;

begin
  Test := AllocMem(length(s)*2);
  try
    Test1:=StringToWideChar(s,Test,length(s)*2);
    result := '';
    sm := '';
    for i := 0 to Length(Test1) do begin
      //Result := Result +
      sm := sm + ' ' + inttostr(ord(test1[i]));
    end;
    WriteToLog('Test=' + sm);
  finally
    // Test1 wird hierdurch auch ungültig
    FreeMem(Test,length(s)*2);
  end;
Ich hoffe ihr versteht mein Problem und habt evt. eine Lösung für mich.

Danke schonmal
Thomas
Besucht doch mal http://www.hitziger.net
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.171 Beiträge
 
Delphi 10.4 Sydney
 
#2

Re: Unicode Frage

  Alt 22. Dez 2004, 16:14
Hallo Thomas,

das was Du machst ist völlig falsch.

Die einzelnen Zeichen (z.B. € = $80) können in der Unicodedarstellung komplett ander Codierung haben (€ = $20AC).

Delphi erledigt das - wenn es um Zeichen der aktuellen Codepage geht - völlig automatisch:

Delphi-Quellcode:
var
  str: String;
  wStr: WideString;
begin
  str := 'Hallo öäü €';
  wStr := str
end;
Willst Du nun einen Verzeichnisnamen in der Unicode-Darstellung haben, so mußt Du die entsprechenden Win32-API-Befehle in der Unicode-Repräsentation aufrufen (Im TNT-Projekt sind liegen z.B. TOpenDialog in einer Unicode-Version vor).

Hat nun ein russischer User auf einem russischen (kyrilischen) Windows dein Delphi-Programm, so ist dein Programm ohne weiteres fähig mit Verzeichnissen umzugehen, welche kyrilische Zeichen enthält (jedenfalls die 128 gebräuchlichsten), da an stelle unserer Sonderzeichen (€ - ÿ) die russischen Zeichen in den 8-Bit-Charatersatz eingeblendet sind. Dafür kann er nichts mit unseren Umlauten üöä anfangen.

Schau dir mal das TNT-Projekt und das Elpack an. Diese beschäftigen sich mit Unicode + Delphi. In der Ausgabe 5.2003 der Zeitschrift "Der Entwickler" habe ich auch einen Artikel zum Thema Delphi+Unicode geschrieben.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Benutzerbild von hitzi
hitzi

Registriert seit: 2. Jan 2003
Ort: Eibau
768 Beiträge
 
Delphi 2010 Professional
 
#3

Re: Unicode Frage

  Alt 22. Dez 2004, 17:03
So einfach ist es in meinem Fall nicht. Mit meinem Programm kommuniziere ich mit einem Handy mit Hilfe des Obexprotokols. Die ganze Kommunikation läuft über einen Comport.

Die Verzeichnisse werden auch korrekt dargestellt - sprich das Auslesen und Umwandeln, der vom Handy gelieferten Daten, in einen String funktioniert wunderbar mit folgender Funktion:

Delphi-Quellcode:
function TObex.AnsiToStr(s : AnsiString) : string;

function ReplaceEntity(s : string; entity : string = ''; replace : string = '') : string;
const cHex = '&#';
      cSep = ';';
var d : string;
begin
  if (entity <> '')and(replace <> '') then begin
    while pos(entity, s) > 0 do s := copy(s, 1, pos(entity, s) - 1) + replace + copy(s, pos(entity, s) + length(entity), length(s));
  end else begin
    while pos(cHex, s) > 0 do begin
      d := copy(s, pos(cHex, s) + length(cHex), length(s));
      d := copy(d, 1, pos(cSep, d) - 1);
      entity := cHex + d + cSep;
      replace := chr(StrToInt('$' + d));
      s := copy(s, 1, pos(entity, s) - 1) + replace + copy(s, pos(entity, s) + length(entity), length(s));
    end;
  end;
  result := s;
end;

var Res : array of WideChar;
    len : integer;
begin
  result := '';
  len := MultiByteToWideChar(CP_UTF8, 0, PChar(s), - 1, nil, 0);
  if len > 0 then begin
    setlength(Res, len);
    MultiByteToWideChar(CP_UTF8, 0, PChar(s), -1, @Res[0], len);
    result := WideString(PWideChar(@Res[0]));
  end;
  if result <> 'then begin
    result := ReplaceEntity(result, '<', '<');
    result := ReplaceEntity(result, '&gt', '>');
    result := ReplaceEntity(result, '&amp;', '&');
    result := ReplaceEntity(result, '&quot;', '"');
    result := ReplaceEntity(result, '&apos;', '''');
    result := ReplaceEntity(result);
  end;
end;
Umgekehrt hatte ich das immer mit der schon oben geposteten Funktion (einfach vor jedes Zeichen ein $#00 und den String mit $#00 abschließen) veranstaltet und bisher keine Probleme gehabt.

Um nun ein Verzeichnis zu wechseln wird der Verzeichnisname genommen, durch die Funktion aus dem ersten Post gejagt (und noch einiges mehr wegen dem Obex Protokol) und das ganze dann als String über den Comport an das Handy geschickt.

Wenn nun bei dem russischen User (Handy auf russisch) ein Verzeichnis auf dem Handy gewechselt werden soll, liefert mir der Obex Server im Handy den "Nicht gefunden" Fehler zurück. Von daher tippe ich auf eine falsche Umwandlung des Verzeichnisnamen. Laut Protokol arbeitet der Obexserver mit Unicode.

Vielleicht hast du noch einen Tipp für mich.
Thomas
Besucht doch mal http://www.hitziger.net
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.171 Beiträge
 
Delphi 10.4 Sydney
 
#4

Re: Unicode Frage

  Alt 22. Dez 2004, 20:59
Im obigen Beispielcode sehe ich CP_UTF8. Da ich das Obex Protokol nicht kenne vermute ich mal das die Kommunikation UTF-8-Codiert abläuft (Der Server wird dann wieder die UTF8-Daten nach Unicode umwandeln).

Dann würde ich dir folgende Umwandlung vorschlagen:

Wandle deinen String nach Widestring um (Automatisch von Delphi per "Compiler Magic").
Diesen Widestring wandelst Du nach UTF-8 um.

Erhalten Strings gehen den Umgekehrten Weg
UTF8 -> Widestring -> String

Dazu kannst Du die Funktionen in System.pas verwenden:
Delphi-Quellcode:
function UTF8Encode(const WS: WideString): UTF8String;
function UTF8Decode(const S: UTF8String): WideString;
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Dimonka

Registriert seit: 7. Mai 2003
5 Beiträge
 
Delphi 7 Enterprise
 
#5

Re: Unicode Frage

  Alt 23. Dez 2004, 14:02
Ich bin nicht sicher, ob ich problem richtig verstanden, aber hier ist ein Hint:
Du soltest CodePage fuer Strings benutzen:

Delphi-Quellcode:
function WideStringToString(const ws: WideString; codePage: Word): AnsiString;
var
  l: integer;
begin
  if ws = 'then
    Result := ''
  else
  begin
    l := WideCharToMultiByte(codePage,
      WC_COMPOSITECHECK or WC_DISCARDNS or WC_SEPCHARS or WC_DEFAULTCHAR,
      @ws[1], - 1, nil, 0, nil, nil);
    SetLength(Result, l - 1);
    if l > 1 then
      WideCharToMultiByte(codePage,
        WC_COMPOSITECHECK or WC_DISCARDNS or WC_SEPCHARS or WC_DEFAULTCHAR,
        @ws[1], - 1, @Result[1], l - 1, nil, nil);
  end;
end; { WideStringToString }

function StringToWideString(const s: AnsiString; codePage: Word): WideString;
var
  l: integer;
begin
  if s = 'then
    Result := ''
  else
  begin
    l := MultiByteToWideChar(codePage, MB_PRECOMPOSED, PChar(@s[1]), - 1, nil, 0);
    SetLength(Result, l - 1);
    if l > 1 then
      MultiByteToWideChar(CodePage, MB_PRECOMPOSED, PChar(@s[1]),
        - 1, PWideChar(@Result[1]), l - 1);
  end;
end; { StringToWideString }
Die russische CodePage ist 1251
Und fuer die UTF8 Sachen hast du schon antwort bekomen:
Delphi-Quellcode:
function UTF8Encode(const WS: WideString): UTF8String;
function UTF8Decode(const S: UTF8String): WideString;
To beer or not to beer?..
  Mit Zitat antworten Zitat
Antwort Antwort


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 22:11 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