Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Ist mein Programm jetzt wirklich Unicode? Trotz Umwandlung? (https://www.delphipraxis.net/161709-ist-mein-programm-jetzt-wirklich-unicode-trotz-umwandlung.html)

TheMiller 17. Jul 2011 10:22

Ist mein Programm jetzt wirklich Unicode? Trotz Umwandlung?
 
Liste der Anhänge anzeigen (Anzahl: 3)
Hallo,

wie einige sicher wissen, habe ich gestern angefangen, auf Delphi 2009 zu portieren. Da sich ja einiges geändert hat, habe ich natürlich auch einige Fragen.

Vorab: Meine Anzeige und das Speichern von Daten funktioniert soweit richtig, allerdings muss ich bei dem Lesen der Daten mit einem UTF8ToString casten - ich weiß nicht, ob es an der Komponente liegt, an der Delphi VCL oder an was ganz anderem.

Ich habe mal durch das Programm in die Datenbank deutschen, französichen und arabischen Text eingetragen. Hat auch geklappt. Nur bei Titel "Test" (arabisch) zeigt der "????" an - der arabische Text im RichEdit "Test" wurde aber richtig gespeichert und dargestellt.
Allerdings alles nur, wenn ich beim Auslesen UTF8ToString benutze.

Ist das nun alles richtig, oder stimmt da immer noch was nicht? Jetzt erstmal die technischen Einzelheiten und ein paar Screenshots.

Also:
Datenbank: Firebird 2.1 embedded
Zugriff über: Zeos SVN 7.0.1 alpha (angeblich Unicode-fähig mit D2009 und firebird)
Tabellen/Spalten-Charset: UTF8
Tabellen/Spalten-Collate: UTF8
ZConnection.Parameters.Add('codepage=utf8');
ZQuery.Parameters.Add('codepage=utf8');
Schreiben in die DB: ZQuery.ParamsByName('titel').AsString:=Objekt.Tite l;
Lesen aus der DB: Objekt.Titel:=UTF8ToString(ZQuery.FieldByName('titel').AsString);


Mehr habe ich nicht eingestellt. Bilder vom Programm und der Datenbank im Anhang.

Vielen Dank im Voraus!

himitsu 17. Jul 2011 10:27

AW: Ist mein Programm jetzt wirklich Unicode? Trotz Umwandlung?
 
Zitat:

Delphi-Quellcode:
Schreiben in die DB: ZQuery.ParamsByName('titel').AsString:=Objekt.Titel;
Lesen aus der DB: Objekt.Titel:=UTF8ToString(ZQuery.FieldByName('titel').AsString);

Einmal UTF8 und dann wieder nicht?

Entweder auch beim Schreiben ein Umkodieren einbauen,
oder, wenn dieses schon im AsString verbaut ist, dieses beim Lesen weglassen.

TheMiller 17. Jul 2011 10:37

AW: Ist mein Programm jetzt wirklich Unicode? Trotz Umwandlung?
 
Liste der Anhänge anzeigen (Anzahl: 5)
Genau das ist ja mein Problem.

Lasse ich die UTF8ToString-Umwandlung weg, habe ich wieder die encoding-Fehler. Hab grad nochmal ein Bildchen gemacht.

Das verstehe ich ja eben auch nicht... Ich möchte keine AnsiStrings haben. WENN ich schon umstellen muss, dann will ich jetzt auch full-unicode haben ;)

Bilder von der Datenbankdefinition und den neuen Ergebnissen OHNE Utf8ToString habe ich angehängt.

mkinzler 17. Jul 2011 10:41

AW: Ist mein Programm jetzt wirklich Unicode? Trotz Umwandlung?
 
Das Problem scheint aber Zeos zu sein, denn die datenbank verwendet Unicode (UTF8) und Delphi strings sind auch Unicode (UTF-16).

himitsu 17. Jul 2011 10:47

AW: Ist mein Programm jetzt wirklich Unicode? Trotz Umwandlung?
 
Zitat:

Lasse ich die UTF8ToString-Umwandlung weg, habe ich wieder die encoding-Fehler.
Und wenn du mal das UTF8Encode beim Schreiben reinmachst?

Wenn etwas Ansi kann und den Text nicht unbedingt aufwändig verarbeiten/vergleichen muß, dann ist UTF-8 ja nahezu kompatibel zu ANSI.
(darum wurde UTF-8 ja erschaffen und wenn man ganz sicher gehn will, dann kann man UTF-7 nutzen)

mkinzler 17. Jul 2011 10:52

AW: Ist mein Programm jetzt wirklich Unicode? Trotz Umwandlung?
 
Zitat:

Wenn etwas Ansi kann und den Text nicht unbedingt aufwändig verarbeiten/vergleichen muß, dann ist UTF-8 ja nahezu kompatibel zu ANSI.
Die Zeichen, die den ersten 7Bits entsprechen sind die selben. Ich würde aber nicht von Kompatibilität reden, da bei Ansi jedes Zeichen 8Bit hat und bei UTF8 nicht! Sobald Sonderzeichen vorkommen kommt bei der Betrachtung als Ansi Müll raus.
Zitat:

Und wenn du mal das UTF8Encode beim Schreiben reinmachst?
Dann aber als Ansistrinmgs aus der Datenbank Lesen und Schreiben.

TheMiller 17. Jul 2011 11:04

AW: Ist mein Programm jetzt wirklich Unicode? Trotz Umwandlung?
 
Liste der Anhänge anzeigen (Anzahl: 3)
Das wäre wirklich seehr ungünstig.

Habt ihr eine Idee, wie ich die Zeos-Codes patchen kann, oder soll ich "einfach" umsteigen. Falls letzteres, würde ich euch gerne fragen, welche kostenlosen Alternativen es gibt. Ich kann mir derzeit für dieses Programm nicht noch eine Komponente kaufen.

(Ja ich weiß, an einer Datenbankkomponente sollte man nicht sparen.. einmal investiert und dann quasi problemfrei. Das mag richtig sein - geht aber wirklich nicht ;) )

PS: Die Zeos-Entwicklung scheint ja auch nicht mehr richtig weiter zu gehen, oder?

Rote Box:

Also, hab nochmal neue Bilder/Einträge gemacht, mit/ohne utf8encode etc. Im JVRichEdit wird IMMER das richtige angezeigt, egal wie ich speicher. Das verwirrt. In der TreeView und dem Label tauchen die encoding-Fehler auf.

mirage228 17. Jul 2011 11:42

AW: Ist mein Programm jetzt wirklich Unicode? Trotz Umwandlung?
 
Also ich hatte letztens auch Probleme mit Zeos und der Codierung. Bei mir waren es Probleme in die Senderichtung beim Speichern von neuen Einträgen.
Hast Du sonst mal die neueste SVN REV von Zeos probiert?
Im Forum bei denen wurden bereits andere Unicode Fixes diskutiert, musst mal schauen ob die bereits ins SVN eingeflossen sind ...

Aber an sich hast du Recht, dass die Aktivität bei Zeos insgesamt gesehen recht gering geworden ist...

Viele Grüße

TheMiller 17. Jul 2011 12:00

AW: Ist mein Programm jetzt wirklich Unicode? Trotz Umwandlung?
 
Ich habe mir gestern via TortoiseSVN die wohl neusten gezogen. Also muss ich wechseln, oder? Was wäre empfehlenswert?

OrNEC 17. Jul 2011 12:45

AW: Ist mein Programm jetzt wirklich Unicode? Trotz Umwandlung?
 
Also ich musste eine Anwendung in Delphi 2009 ganz neu schreiben, damit es 100% tig Unicodefähig ist. Einfach ein altes Projekt in Delphi 2009 zu öffnen und weiter machen geht ohne Unicodeprobleme nicht.

USchuster 17. Jul 2011 12:46

AW: Ist mein Programm jetzt wirklich Unicode? Trotz Umwandlung?
 
Ich kann zu ZEOS + Unicode + Firebird leider nichts sagen, aber falls ZEOS TStringField anstatt TWideStringField für die Stringfelder generiert, dann liegt das Problem dort und das kann wahrscheinlich über eine Option gesteuert werden. Den ganzen Quelltext jetzt mit UTF-8 de-/encoding zu versehen ist sicher nicht im Sinne des Erfinders.

Aus $(BDS)\source\db\DB.pas
Delphi-Quellcode:
function TStringField.GetAsString: string;
begin
  Result := string(GetAsAnsiString);
end;

himitsu 17. Jul 2011 12:50

AW: Ist mein Programm jetzt wirklich Unicode? Trotz Umwandlung?
 
jupp, das hatte ich letztens auch bei TClientDataSet (ohne DB-Anbindung) gesehn.

String und Memo sind im D2010 weiterhin AnsiString.
Erst wenn man die Felder geziehlt als ftWideString und ftWideMemo deklariert hat, kann es Unicode.

TheMiller 17. Jul 2011 12:52

AW: Ist mein Programm jetzt wirklich Unicode? Trotz Umwandlung?
 
Naja, ich hab alle Datenbank-Anfragen in einer Klasse gekapselt. Das dürfte weniger das Problem sein...

TheMiller 17. Jul 2011 13:27

AW: Ist mein Programm jetzt wirklich Unicode? Trotz Umwandlung?
 
Sorry, ich habe die Antworten weiter oben nicht gesehen (wg. iPhone).

Ja, ich kann nicht die Quelltexte von Zeos ändern - will ich auch nicht. Aber es muss irgendeine Lösung her.

Bin auch fast schon gewillt, umzusteigen und evtl sogar was zu kaufen. Nur hätte ich gerne Empfehlungen, nicht dass ich dann auch noch doppelt bezahlen muss, weil ich mich "vergriffen" hab.

mkinzler 17. Jul 2011 13:34

AW: Ist mein Programm jetzt wirklich Unicode? Trotz Umwandlung?
 
Wenn es etwas kosten darf: IBDAC oder UniDAC ( für mehrere DBMS)

RWarnecke 17. Jul 2011 13:36

AW: Ist mein Programm jetzt wirklich Unicode? Trotz Umwandlung?
 
IBObjects und FIBPlus wäre auch noch eine alternative.

TheMiller 17. Jul 2011 13:37

AW: Ist mein Programm jetzt wirklich Unicode? Trotz Umwandlung?
 
UniDAC hab ich schon gefunden. Welche Version ist denn ausreichend? Kommt man mit der Standard-Version hin? In der Professional gibt's ja die Data Access Provider - was ist das? Welche Version würdest du von dieser Komponente empfehlen?

Achso: Mache eigentlich mehr mit MySQL als mit Firebird.

Danke euch soweit!

RWarnecke 17. Jul 2011 13:42

AW: Ist mein Programm jetzt wirklich Unicode? Trotz Umwandlung?
 
Wenn Du eh schon viel mit MySQL machst, dann nehme die UniDAC Professional mit oder ohne Sourcecode (ich habe die Prof ohne Sourcecode und bin voll zufrieden damit). Dann hast Du die größten Datenbanksystem abgedeckt und brauchst Dir in nächster Zeit keine Sorgen mehr machen.

TheMiller 17. Jul 2011 13:47

AW: Ist mein Programm jetzt wirklich Unicode? Trotz Umwandlung?
 
Das habe ich befürchtet ;)

Nagut - ist wahrscheinlich gut investiertes Geld. Ich geh dann mal betteln ;)

Also hake ich die Zeos-Geschichte jetzt ab, ja? Wird wohl das vernünftigste sein!

Ich danke euch für eure Hilfe (quasi in Chat-Geschwindigkeit)!

Wer noch was dazu sagen möchte, kann das natürlich immernoch gerne tun!

Eine Frage noch: Was ist der Unterschied zwischen TUniConnection und der MySQL-Provider Komponente. Was ist der MySQL-Provider?

himitsu 17. Jul 2011 13:49

AW: Ist mein Programm jetzt wirklich Unicode? Trotz Umwandlung?
 
Beitrag #11/#12:
Wie sehen denn die Definitionen deiner Felder aus, also welche bei dir ankommen.
( TDataSet.FieldDefs )

TheMiller 17. Jul 2011 13:59

AW: Ist mein Programm jetzt wirklich Unicode? Trotz Umwandlung?
 
Ich poste mal hier die Methoden, angefangen von der, die ich aufrufe:

Delphi-Quellcode:
ZQuery.FieldByName(Field).AsString;

function TDataSet.FieldByName(const FieldName: string): TField;
begin
  Result := FindField(FieldName);
  if Result = nil then DatabaseErrorFmt(SFieldNotFound, [FieldName], Self);
end;


function TDataSet.FindField(const FieldName: string): TField;
begin
  Result := FFields.FindField(FieldName);
  if (Result = nil) and ObjectView then
    Result := FieldList.Find(FieldName);
  if Result = nil then
    Result := FAggFields.FindField(FieldName);
end;

function TFields.FindField(const FieldName: string): TField;
var
  I: Integer;
begin
  for I := 0 to FList.Count - 1 do
  begin
    Result := FList.Items[I];
    if WideCompareText(Result.FFieldName, FieldName) = 0 then Exit;
  end;
  Result := nil;
end;

function TField.GetAsString: string;
begin
  Result := GetClassDesc;
end;

function TField.GetClassDesc: string;
var
  I, L: Integer;
  S: string;
begin
  S := ClassName;
  I := 1;
  L := Length(S);
  if S[1] = 'T' then
    I := 2;
  if (L-I >= 5) and (CompareText(Copy(S, L - 4, 5), 'FIELD') = 0) then
    Dec(L, 5);
  FmtStr(Result, '(%s)', [Copy(S, I, L + 1 - I)]);
  if not IsNull then
    Result := AnsiUpperCase(Result);
end;

//////////////////////////////////////
Und hier TFieldDefs
//////////////////////////////////////
TFieldDefs = class(TDefCollection)
  private
    FParentDef: TFieldDef;
    FHiddenFields: Boolean;
    function GetFieldDef(Index: Integer): TFieldDef;
    procedure SetFieldDef(Index: Integer; Value: TFieldDef);
    procedure SetHiddenFields(Value: Boolean);
  protected
    procedure FieldDefUpdate(Sender: TObject);
    procedure ChildDefUpdate(Sender: TObject);
    procedure SetItemName(AItem: TCollectionItem); override;
    function GetFieldDefClass: TFieldDefClass; virtual;
  public
    constructor Create(AOwner: TPersistent); virtual;
    function AddFieldDef: TFieldDef;
    function Find(const Name: string): TFieldDef;
    procedure Update; reintroduce;
    { procedure Add kept for compatability - AddFieldDef is the better way }
    procedure Add(const Name: string; DataType: TFieldType; Size: Integer = 0;
      Required: Boolean = False);
    property HiddenFields: Boolean read FHiddenFields write SetHiddenFields;
    property Items[Index: Integer]: TFieldDef read GetFieldDef write SetFieldDef; default;
    property ParentDef: TFieldDef read FParentDef;
  end;
Ich hoffe da ist alles dabei, was du sehen wolltest ...

RWarnecke 17. Jul 2011 14:01

AW: Ist mein Programm jetzt wirklich Unicode? Trotz Umwandlung?
 
Zitat:

Zitat von DJ-SPM (Beitrag 1112240)
Eine Frage noch: Was ist der Unterschied zwischen TUniConnection und der MySQL-Provider Komponente. Was ist der MySQL-Provider?

Mit der UniConnection und dem Provider stellst Du die Verbindung her. Dabei enthält die TUniConnection die Verbindungsdaten. Ohne den Provider gibt es eine Fehlermeldung, wenn Du versuchst die Datenbankverbindung aufzubauen.

himitsu 17. Jul 2011 14:10

AW: Ist mein Programm jetzt wirklich Unicode? Trotz Umwandlung?
 
Zitat:

Zitat von DJ-SPM (Beitrag 1112243)
Ich hoffe da ist alles dabei, was du sehen wolltest ...

Eher weniger :zwinker:

Was gibt denn
Delphi-Quellcode:
ZQuery.FieldByName(Field).FieldType
für deine Stringfelder zurück?


Delphi-Quellcode:
uses TypInfo;

ShowMessage(GetEnumProp(ZQuery.FieldByName(Field), 'FieldType'));

TheMiller 17. Jul 2011 14:55

AW: Ist mein Programm jetzt wirklich Unicode? Trotz Umwandlung?
 
Zitat:

Eher weniger ;)
War ja klar ;)


Bitte entschuldigt die "späte" Antwort ;)

Ich bekomme eine AV mit der Meldung: "Die Eigenschaft "FieldType" existiert nicht.

RWarnecke 17. Jul 2011 15:01

AW: Ist mein Programm jetzt wirklich Unicode? Trotz Umwandlung?
 
Unter Zeos heißt die Eigenschaft DataType und nicht FieldType. Datatype gibt dann einen Integer zurück. Anhand des Integers kann man dann bestimmen, welchen Type das Feld hat. Hier ein Beispiel :
Delphi-Quellcode:
    begin
      case TMPQuery.Fields[IntZaehler].datatype of
        ftUnknown:
          begin
            sType := 'Unknown';
          end;
        ftString:
          begin
            sType := 'String';
          end;
        ftSmallint:
          begin
            sType := 'Smallint';
          end;
        ftInteger:
          begin
            sType := 'Integer';
          end;
        ftWord:
          begin
            sType := 'Word';
          end;
        ftBoolean:
          begin
            sType := 'Boolean';
          end;
        ftFloat:
          begin
            sType := 'Float';
          end;
        ftCurrency:
          begin
            sType := 'Currency';
          end;
        ftBCD:
          begin
            sType := 'BCD';
          end;
        ftDate:
          begin
            sType := 'Date';
          end;
        ftTime:
          begin
            sType := 'Time';
          end;
        ftDateTime:
          begin
            sType := 'DateTime';
          end;
        ftBytes:
          begin
            sType := 'Bytes';
          end;
        ftVarBytes:
          begin
            sType := 'VarBytes';
          end;
        ftAutoInc:
          begin
            sType := 'AutoInc';
          end;
        ftBlob:
          begin
            sType := 'Blob';
          end;
        ftMemo:
          begin
            sType := 'Memo';
          end;
        ftGraphic:
          begin
            sType := 'Graphicc';
          end;
        ftFmtMemo:
          begin
            sType := 'FmtMemo';
          end;
        ftParadoxOle:
          begin
            sType := 'ParadoxOlee';
          end;
        ftDBaseOle:
          begin
            sType := 'DBaseOle';
          end;
        ftTypedBinary:
          begin
            sType := 'TypedBinary';
          end;
        ftCursor:
          begin
            sType := 'Cursor';
          end;
        ftFixedChar:
          begin
            sType := 'FixedChar';
          end;
        ftWideString:
          begin
            sType := 'WideString';
          end;
        ftLargeInt:
          begin
            sType := 'LargeInt';
          end;
        ftADT:
          begin
            sType := 'ADT';
          end;
        ftArray:
          begin
            sType := 'Array';
          end;
        ftReference:
          begin
            sType := 'Reference';
          end;
        ftDataSet:
          begin
            sType := 'DataSet';
          end;
        ftOraBlob:
          begin
            sType := 'OraBlob';
          end;
        ftOraClob:
          begin
            sType := 'OraClob';
          end;
        ftVariant:
          begin
            sType := 'Variant';
          end;
        ftInterface:
          begin
            sType := 'Interface';
          end;
        ftIDispatch:
          begin
            sType := 'IDispatch';
          end;
        ftGuid:
          begin
            sType := 'Guid';
          end;
      end;
Wie gesagt, ist nur aus einem Programm rauskopiert.

TheMiller 17. Jul 2011 15:03

AW: Ist mein Programm jetzt wirklich Unicode? Trotz Umwandlung?
 
Hi.

Aber auch ein
Delphi-Quellcode:
ShowMessage(GetEnumProp(db.DBQuery.FieldByName('TITEL'), 'DataType'));
bringt die gleiche AV.


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