Einzelnen Beitrag anzeigen

peterbelow

Registriert seit: 12. Jan 2019
Ort: Hessen
701 Beiträge
 
Delphi 12 Athens
 
#2

AW: Einfügen von RTF Text am TRichEdit.SelStart

  Alt 14. Dez 2023, 13:16
Hallo,

mittels TRichEdit.SelStart := '{\...}';

kann ich neuen Text in ein RTF Dokument einfügen.
Allerdings sind das dann Roh-Daten.
Heißt: so, wie die Daten/Zeichenkette im Programmtext stehen, so wird momentan dieser Text in das TRichEdit eingefügt (unabhängig davon, ob nun das Plain oder RTF Text ist), beginnend ab der Position des Text-Caret.

Frage:
Gibt es eine Möglichkeit RTF-Text innerhalb eines RTF-Textes einzufügen - was muss beachtet werdem ?
Das geht mittels EM_STREAMIN. Ich habe einen uralten Post über dieses Thema in meinem Archiv gefunden, vielleicht hilft Dir das weiter. Das war sicher für eine alte Windows-Version, check also besser die aktuelle Dokumentation für EM_STREAMIN.

Delphi-Quellcode:
Getting formatted text in and out of a TRichedit. Project needs
3 TButtons, 1 TMemo, 1 TRichEdit, 1 TColorDialog, 1 TFontDialog,

Uses RichEdit;

Type
  TEditStreamCallBack = function (dwCookie: Longint; pbBuff: PByte;
    cb: Longint; var pcb: Longint): DWORD; stdcall;

  TEditStream = record
    dwCookie: Longint;
    dwError: Longint;
    pfnCallback: TEditStreamCallBack;
  end;

function EditStreamInCallback(dwCookie: Longint; pbBuff: PByte;
 cb: Longint; var pcb: Longint): DWORD; Stdcall;
var
  theStream: TStream;
  dataAvail: LongInt;
begin
  theStream := TStream(dwCookie);
  with theStream do begin
    dataAvail := Size - Position;
    Result := 0; {assume everything is ok}
    if dataAvail <= cb then begin
      pcb := Read(pbBuff^, dataAvail);
      if pcb <> dataAvail then {couldn't read req. amount of bytes}
        result := DWORD(E_FAIL);
    end
    else begin
      pcb := Read(pbBuff^, cb);
      if pcb <> cb then
        result := DWORD(E_FAIL);
    end;
  end;
end;


Function EditStreamOutCallback(dwCookie: Longint; pbBuff: PByte;
    cb: Longint; var pcb: Longint): DWORD; stdcall;
 var
   theStream: TStream;
 begin
   theStream := TStream(dwCookie);

   with theStream do begin
     If cb > 0 Then
       pcb := Write(pbBuff^, cb);
     Result := 0;
   end;
 end;

Procedure GetRTFSelection( aRichEdit: TRichEdit; intoStream: TStream );
Var
  editstream: TEditStream;
Begin
  With editstream Do Begin
    dwCookie:= Longint(intoStream);
    dwError:= 0;
    pfnCallback:= EditStreamOutCallBack;
  end;
  aRichedit.Perform( EM_STREAMOUT, SF_RTF or SFF_SELECTION, longint(@editstream));
End;

Procedure PutRTFSelection( aRichEdit: TRichEdit; sourceStream: TStream );
Var
  editstream: TEditStream;
Begin
  With editstream Do Begin
    dwCookie:= Longint(sourceStream);
    dwError:= 0;
    pfnCallback:= EditStreamInCallBack;
  end;
  aRichedit.Perform( EM_STREAMIN, SF_RTF or SFF_SELECTION, longint(@editstream));
End;

procedure TForm1.Button2Click(Sender: TObject);
Var
  aMemStream: TMemoryStream;
begin
  aMemStream := TMemoryStream.Create;
  try
    GetRTFSelection( richedit1, aMemStream );
    aMemStream.Position := 0;
    memo1.Lines.LoadFromStream( aMemStream );
  finally
    aMemStream.Free;
  end;
end;

procedure TForm1.Button3Click(Sender: TObject);
Var
  aMemStream: TMemoryStream;
begin
  aMemStream := TMemoryStream.Create;
  try
    memo1.Lines.SaveToStream( aMemStream );
    aMemStream.Position := 0;
    PutRTFSelection( richedit1, aMemStream );
  finally
    aMemStream.Free;
  end;
end;

procedure TForm1.RichEdit1KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  If [ssCtrl] = Shift Then
    Case Key of
      Ord('B'): With (Sender As TRichEdit).SelAttributes Do
                  If fsBold In Style Then
                    Style := Style - [fsBold]
                  Else
                    Style := Style + [fsBold];
      Ord('U'): With (Sender As TRichEdit).SelAttributes Do
                  If fsUnderline In Style Then
                    Style := Style - [fsUnderline]
                  Else
                    Style := Style + [fsUnderline];
      Ord('I'): With (Sender As TRichEdit).SelAttributes Do
                  If fsItalic In Style Then
                    Style := Style - [fsItalic]
                  Else
                    Style := Style + [fsItalic];
      Ord('T'): If ColorDialog1.Execute Then
                  (Sender As TRichEdit).SelAttributes.Color := ColorDialog1.Color;
      Ord('F'): If FontDialog1.Execute Then
                  (Sender As TRichEdit).SelAttributes.Assign( FontDialog1.Font );
    End; { Case }
end;

procedure TForm1.RichEdit1KeyPress(Sender: TObject; var Key: Char);
begin
  {Ctrl-I yields a #9 character, a Tab. We have to swallow that. }
  If (Key = #9) and (GetKeyState( VK_CONTROL ) < 0) Then
    Key := #0;
end;

You now have a simple rich text editor and can type some formatted text
into the rich edit. Select some of it and click button2. The selection is
fetched and copied as RTF text into the memo. Put the caret somewhere in
the rich edit and click button3. The RTF text from the memo is inserted at
the selection into the rich edit. To combine several snippets of RTF text
into one block one would have to remove the trailing } from block 1, the
leading {\rtf1 from block 2 and copy both together into a new block. You
can test that with a little cut and paste on the memo before you hit
button3.

Note that this technique still requires you to select each block of RTF
text before you can copy it out of the rich edit control. It is this rapid
selection and deselection that causes the control to flicker but i see no
way around it. You could use an off-screen rich edit for this work,
however.}
Peter Below
  Mit Zitat antworten Zitat