user2618164
user2618164

Reputation: 23

How to copy specific lines from one TRichEdit control to another?

I'm new with delphi and I'm trying to figure out how to load specific lines (and not the complete text) from one richtextbox to another one.

procedure TForm1.richedit1change(Sender: TObject);
var
  ms: TMemoryStream;
begin
  ms := TMemoryStream.Create;
  try
    RichEdit1.Lines.SaveToStream(ms);
    ms.Seek(0, soFromBeginning);

    RichEdit2.Lines.LoadFromStream(ms);
  finally
    ms.Free;
  end;
end;

Upvotes: 0

Views: 4106

Answers (1)

LU RD
LU RD

Reputation: 34939

You do not need a stream to transfer text lines from one TRichEdit to another. Just use the Lines property. Lines is a TStrings type, so use its methods for manipulating the TRichEdit text.

procedure TForm1.richedit1change(Sender: TObject);
var
  i: Integer;
begin
  RichEdit2.Lines.Clear;
  for i := 0 to Pred(RichEdit1.Lines.Count) do
  begin
    if YourSpecificTestFunction(i) then
      RichEdit2.Lines.Add(RichEdit1.Lines[i]);
  end;
end;

If you want to preserve the RTF formatting, you can use the technique described by Zarko Gajic, Append or Insert RTF from one RichEdit to Another.

Another simple option would be to use the windows clipboard and the TRichEdit.Selection:

procedure CopyRichEditSelection(Source,Dest: TRichEdit);
begin
  // Copy Source.Selection to Dest via ClipBoard.
  Dest.Clear;
  if (Source.SelLength > 0) then
  begin
    Source.CopyToClipboard;        
    Dest.PasteFromClipboard;
  end;
end;

This will also preserve your formatting, copying the selected parts.

If you want to control the selection without user control, use TRichEdit.SelStart to position the caret to the character where the selection starts, and SelLength for the selection length. To position the caret on a specific line, use:

RichEdit1.SelStart := RichEdit1.Perform(EM_LINEINDEX, Line, 0);

If you don't want to use windows clipboard for the copy/paste operation, a stream can be used:

Uses RichEdit;

function EditStreamOutCallback(dwCookie: DWORD_PTR; pbBuff: PByte; cb: Longint;
  var pcb: LongInt): LongInt; stdcall;
begin
  pcb := cb;
  if cb > 0 then
  begin
    TStream(dwCookie).WriteBuffer(pbBuff^, cb);
    Result := 0;
  end
  else
    Result := 1;
end;

procedure GetRTFSelection(aRichEdit: TRichEdit; intoStream: TStream);
type
  TEditStreamCallBack = function (dwCookie: DWORD_PTR; pbBuff: PByte;
    cb: Longint; var pcb: Longint): Longint; stdcall;

  TEditStream = packed record // <-- Note packed !!
    dwCookie: DWORD_PTR;
    dwError: Longint;
    pfnCallback: TEditStreamCallBack;
  end;

var
  editstream: TEditStream;
begin
  with editstream do
  begin
    dwCookie := DWORD_PTR(intoStream);
    dwError := 0;
    pfnCallback := EditStreamOutCallBack;
  end;
  aRichedit.Perform( EM_STREAMOUT, SF_RTF or SFF_SELECTION, LPARAM(@editstream));
end;

procedure CopyRichEditSelection(Source,Dest: TRichEdit);
var
  aMemStream: TMemoryStream;
begin
  Dest.Clear;
  if (Source.SelLength > 0) then
  begin
    aMemStream := TMemoryStream.Create;
    try
      GetRTFSelection(Source, aMemStream);
      aMemStream.Position := 0;
      Dest.Lines.LoadFromStream(aMemStream);
    finally
      aMemStream.Free;
    end;
  end;
end;

Upvotes: 3

Related Questions