Autor Beitrag
Kanne
Hält's aus hier
Beiträge: 6



BeitragVerfasst: Mi 07.01.09 12:03 
Hi,

ich muss einen EMF-Konverter schreiben und habe folgendes Problem:
ich kann zwar Texte aus einem .EMF-File einlesen und überarbeiten,
bekomme den neuen String aber nicht in die Datei zurückgeschrieben
(eine analoge Programmierung mit .WMF funktioniert hingegen)

Beispiel .WMF:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
FldTxt: string;
txt: array [1..1024] of Char;

    BlockRead(fData, txt, vTxt.txtL);
    FldTxt := Copy(txt, 1, vTXT.txtL);
    FldTxt := Trim(LowerCase(FldTxt));
    StrPCopy(@txt, FldTxt);
    BlockWrite(fNew, txt, NewLen);

Beispiel .EMF:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
FldTxt, TmpTxt: Widestring;
txt: array [1..1024] of WideChar;

    BlockRead(fData, txt, vTxt.txtL * 2); { UNICODE = 2 Byte ! }
    FldTxt := Copy(txt, 1, vTXT.txtL);
    FldTxt := Trim(LowerCase(FldTxt));
    StrPCopy(@txt, FldTxt); {fehlerhaft => anscheinend nicht UNICODE-fähig !}

    BlockWrite(fNew, txt, NewLen * 2);


Frage letztlich:
wie bekomme ich einen Widestring per BlockWrite in eine Binärdatei ?

P.S.:
in den WMF / EMF stehen die Textzeichen OHNE Null-Endung,
dafür gibt's vorher eine Struktur mit Längenangabe (vTXT.txtL)

Moderiert von user profile iconGausi: Delphi-Tags hinzugefügt
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 07.01.09 12:40 
Wie wäre es mit CopyMemory?
Aber kannst du den WideString nicht direkt schreiben? Mit einem normalen String geht das doch auch.
Kanne Threadstarter
Hält's aus hier
Beiträge: 6



BeitragVerfasst: Mi 07.01.09 14:11 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Wie wäre es mit CopyMemory?
Aber kannst du den WideString nicht direkt schreiben? Mit einem normalen String geht das doch auch.


Ich muss die einzelnen Zeichen aus dem String in die Datei bringen;
CopyMemory geht nicht, da ja der String am Anfang die Längenangabe stehen hat,
letztlich das gleiche Problem, wie beim Schreiben mit "BlockWrite(fNew, FldTxt, NewLen * 2);"
dann steht dort zunächst ja die Verwaltungsteil vom String.

Sinngemäß kann ich natürlich per CopyMemoy das ganze in das Array übertragen und dann
das Array ab Pos. x schreiben (per Offset den String-Header sozusagen übergehen) ...
aber das muss doch einfacher gehen !
Also sowas wie "StrPWideCopy()": WideString => Array of WideChar ...
kann man natürlich notfalls auch per Schleife Zeichenweise übertragen
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 07.01.09 14:17 
user profile iconKanne hat folgendes geschrieben Zum zitierten Posting springen:
CopyMemory geht nicht, da ja der String am Anfang die Längenangabe stehen hat,
letztlich das gleiche Problem, wie beim Schreiben mit "BlockWrite(fNew, FldTxt, NewLen * 2);"
dann steht dort zunächst ja die Verwaltungsteil vom String.
Das stimmt so nicht, dass das gar nicht geht. ;-)
Schau mal hier, da habe ich das für Strings auch benutzt:
www.delphi-forum.de/....php?p=535934#535934

Dabei habe ich in und aus einem Array kopiert, aber genau so kann man eben auf den Speicherbereich mit den Buchstaben direkt zugreifen. Die Verwaltungsdaten stehen davor, du musst nur die Adresse des ersten Buchstabens als Beginn des Speicherbereichs nehmen. ;-)
Kanne Threadstarter
Hält's aus hier
Beiträge: 6



BeitragVerfasst: Mi 07.01.09 15:17 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconKanne hat folgendes geschrieben Zum zitierten Posting springen:
CopyMemory geht nicht, da ja der String am Anfang die Längenangabe stehen hat,
letztlich das gleiche Problem, wie beim Schreiben mit "BlockWrite(fNew, FldTxt, NewLen * 2);"
dann steht dort zunächst ja die Verwaltungsteil vom String.
Das stimmt so nicht, dass das gar nicht geht. ;-)
Schau mal hier, da habe ich das für Strings auch benutzt:
www.delphi-forum.de/....php?p=535934#535934

Dabei habe ich in und aus einem Array kopiert, aber genau so kann man eben auf den Speicherbereich mit den Buchstaben direkt zugreifen. Die Verwaltungsdaten stehen davor, du musst nur die Adresse des ersten Buchstabens als Beginn des Speicherbereichs nehmen. ;-)


hm, wusste gar nicht, dass man auf die einzelnen Zeichen eines String mit [] zugreifen kann ...
habe bisher für String-Änderungen immer die Builtin-Funktionen benutzt.

Wie auch immer ... scheint so zu funktionieren:
mit FldTxt[1] komme ich an die richtige Adresse und kann somit das ganze per
CopyMemory kopieren oder mir das ganze sparen und sofort den BlockWrite ändern:

CopyMemory(@txt, @FldTxt[1], length(FldTxt) * sizeof(WideChar));
BlockWrite(fNew, Txt, NewLen * 2);
bzw.
BlockWrite(fNew, FldTxt[1], NewLen * 2);

Schöner wäre natürlich, wenn "StrPCopy(@txt, FldTxt);" auch mit WideString funktioniert hätte ...


Vielen Dank für die tolle Hilfe ... echt klasse !