SavetoString('RTF') verliert Feldformatierungen beim zurück laden

  • Hallo,

    in einem WPRichText sind Textfelder, die mit WPRichText.InputMergeField eingefügt wurden.

    Weiterhin gibt es normalen Text.

    Einzelne Textfelder sind fett formatiert und haben eine größere Schrift.

    Dieses WPRichtext wird als RTF-Text weggespeichert mit s := WP.SaveToString('RTF',false);

    und s zeigt im Debugger

    Code
    '{\rtf1\ansi\deff0\uc1\ansicpg1252\deftab720{\fonttbl{\f0\fnil\fcharset1 Arial;}{\f1\fnil\fcharset2 Wingdings;}{\f2\fnil\fcharset2 Symbol;}{\f3\fnil\fcharset3 Segoe UI Emoji;}}{\colortbl\red0\green0\blue0;\red255\green0\blue0;\red0\green128\blue0;\red0\green0\blue255;\red255\green255\blue0;\red255\green0\blue255;\red128\green0\blue128;\red128\green0\blue0;\red0\green255\blue0;\red0\green255\blue255;\red0\green128\blue128;\red0\green0\blue128;\red255\green255\blue255;\red192\green192\blue192;\red128\green128\blue128;\red0\green0\blue0;}\wpprheadfoot1\paperw4875\paperh4715\margl0\margr0\margt0\margb0\headery254\footery254\ftnbj\sftnbj\sftnrstcont\nocolbal\sftnnar\saftnnar\fet0\endnhere\sectdefaultcl{\*\generator WPTools_9.0-PRM;}{\plain\f0\fs28\cf0{\field{\*\fldinst{MERGEFIELD Formularfeld_1-42}}{\*\wpfldparam{Kundenberatungs GmbH}}{\fldrslt{\f0\fs40\cf0\b\i Kundenberatungs GmbH\f0\fs28\cf0\b0\i0}}}\par'#$D#$A'\plain\f0\fs28\cf0{\field{\*\fldinst{MERGEFIELD Formularfeld_2-46}}{\*\wpfldparam{Kundenweg 12}}{\fldrslt{Kundenweg 12}}}\par'#$D#$A'\pard\plain\plain\f0\fs28\cf0\par'#$D#$A'\plain\f0\fs28\cf0{\field{\*\fldinst{MERGEFIELD Formularfeld_3-47}}{\*\wpfldparam{98765}}{\fldrslt{\f0\fs38\cf0\b 98765\f0\fs28\cf0\b0}}}\li0\fi0\ri0\sb0\sa0\ql\vertalt\f0\fs38\cf0\b  \f0\fs28\cf0\b0{\field{\*\fldinst{MERGEFIELD Formularfeld_4-48}}{\*\wpfldparam{Kundendorf}}{\fldrslt{\f0\fs38\cf0\b Kundendorf\f0\fs28\cf0\b0}}}\par'#$D#$A'}}'

    Da sind also die Felder und ihre Schriftgrößen drin.

    Num erzeuge ich in einem anderen WPRichText Textboxen und möchte da diesen RTF-Inhalt reinbekommen

    Warum gehen die Formatierungen verloren?

    Ciao
    Stefan

    3 Mal editiert, zuletzt von skoschke (28. Februar 2020 um 11:01)

    • Offizieller Beitrag

    Es ist nicht sinnvoll bei RTF text mit strings zu arbeiten, verwenden Sie memory streams. RTF ist ANSI code und man kann nie wissen, ob bei der Umwandlung in einen unicode string eine code page umwandlung den code verändert. Desweiteren kann man einen memorystream immer leicht als Datei abspeichern, für debugging zwecken.

    Ich habe Ihren text hier mal in eine Textbox geladen, ich sehe schon die unterschiedlichen Grössen.

    Einen String konnte ich nicht bauen, da Ihre Debugger Quelle dafür keine Vorlage darstellt.

    • Offizieller Beitrag

    Das macht hier keinen Unterschied:

    var RTFData: TWPRTFDataBlock;

    mem : TMemoryStream;

    obj : TWPTextObj;

    begin

    mem := TMemoryStream.Create;

    mem.LoadFromFile('S:\rtf.rtf');

    WPRichText1.ActiveText := WPRichText1.HeaderFooter.Get(wpIsHeader,wpraOnAllPages);

    obj := WPRichText1.TextObjects.InsertTextBox(3000,3000, RTFData);

    RTFData.RtfText.LoadFromStream(mem);

    mem.Free;

  • Kurze Rückmeldung:

    Nach langem Suchen habe ich die Stelle gefunden, wo bei mir nicht konsequent AnsiString verwendet wurde.

    Das war die Stelle, wo ich die Inhalte vieler kleiner WPRichText an ein großes per dok.RTFVariables.AddStream... angehängt hatte.

    Jetzt funktioniert alles wie gewünscht.

    Ciao
    Stefan

  • Hallo,

    nein, leider habe ich mich zu früh gefreut...

    "Normale Texte mit unterschiedlichen Schriften" werden korrekt geladen, aber Mergefields, welche in dem WPRichText stecken, verlieren weiterhin ihre Formatierungen.

    Ich habe den Inhalt des WPRichText mit

    Code
    ms:=TMemoryStream.Create;
    WP.SaveToStream(ms,'RTF');
    ms.SaveToFile('c:\temp\RTFStream.rtf');
    ms.free;

    gespeichert.

    Im GetSpecialText dann wieder laden:

    Code
    ...
    txtobj := WPRichText1.TextObjects.InsertTextBox(b, h, RTFData);
    ...
    if RTFData <> nil then
       begin
         ms := TMemoryStream.Create;
         ms.LoadFromFile('c:\temp\RTFStream.rtf');
         RTFData.RtfText.LoadFromStream(ms, 'RTF');
         ms.Free;
       end;

    Die gespeicherte Datei habe ich mal per Mail gesendet.

    Ciao
    Stefan

  • Hallo,

    ich denke ich habe mein Problem besser lokalisiert:

    Beim per ButtonClick die Textbox erzeugen wird auch die Feldformatierung korrekt dargestellt, mache ich das Laden allerdings im GetSpecialText dann sind die Feldformatierungen weg.

    ButtonClick:

    Was ist denn an dem Code im GetSpecialText falsch?

    Ciao

    Stefan

    • Offizieller Beitrag

    Der code entspricht ja ungefähr der demo TextBoxTestU und ist ok, und wenn ich die demo entsprechend ergänze, kommen die Attribute dort auch an.

    Wichtig ist beim event GetSpecialText lediglich, das dort weder formatiert werden darf, noch die cursor position verändert. Dies macht obiger code aber nicht.

    Am besten nach dem Laden den gesamten Text abspeichern, um zu prüfen, ob die Attribute noch da sind. Evtl. werde sie ja nach dem Laden durch einen Event überschrieben.

    Anregung: Wann wird denn GetSpecialText ausgelöst? Wenn Sie einen breakpoint platzieren, was liegt auf dem stack?

  • Hallo,

    der Stack ist "unauffällig", was ich jetzt gefunden habe, ist dass die Formatierungen im MailMergeGetText kaputtgehen!

    Der sieht momentan etwa so aus:

    Code
     procedure TForm.WPRichText1MailMergeGetText(Sender: TObject;
      const inspname: string; Contents: TWPMMInsertTextContents);
    var
      S: string;
    begin
        //hier wird eigentlich der anzuzeigende Text gemäß inspname geholt
        S:= 'Hallo'
        Contents.StringValue := S;
    end;

    Ich vermute die Contents.Options sind fehlerhaft, nur habe ich beim Probieren keine Option gefunden welche die bestehende Formatierung nicht kaputtmacht.

    Gibt es dazu einen Tip bitte?

    Ciao

    Stefan

    • Offizieller Beitrag

    Es wird also MergeText nach dem Einfügen des Textes aufgerufen und dabei gehen die Attribute verloren, nicht wegen SaveToString!

    Achten Sie bitte darauf, dass die Einfügepunkte << >> das text Attribut besitzen, welches auch der enthaltene Text haben soll.

    Das ist immer wichtig, ob die Felder im header, footer, text box oder im body sind.

    Der Text innerhalb von << >> ist nicht das Feld, sondern der Feldinhalt. Dieser Text ist optional und kann ersetzt werden, er kann auch fehlen.

    Man kann die Attribute des Textes aber so auslesen (--> Mail Merge):

    Contents.MergeAttr.CharAttr := WPRichText1.CPCharAttr;