Link to home
Start Free TrialLog in
Avatar of SteveFarndon2000
SteveFarndon2000Flag for United Kingdom of Great Britain and Northern Ireland

asked on

How do I insert text into a TRichEdit control at the current carat position?

Hello Experts,

What I want to do is to give the user the facility to insert a pre-defined string into a TRichEdit control box by clicking on a button. The string must be inserted at the current carat position.

I used the code in the article at http://delphi.about.com/od/tmemotrichedit/a/richedit-append.htm which shows how to insert/append text from one TRichEdit control to another. This worked (almost). One problem - a line-break appears at the end of the inserted text.

Code from the article is shown below.

Full points go to anyone who can fix this or provide an alternative solution.

This looks very difficult hence the high tariff.

Thank you!
uses RichEdit;

procedure AppendToRichEdit(const source, destination : TRichEdit) ;
var
  rtfStream: TEditStream;
  sourceStream : TMemoryStream;

  function EditStreamReader(
    dwCookie: DWORD;
    pBuff: Pointer;
    cb: LongInt;
    pcb: PLongInt): DWORD; stdcall;
  begin
    result := $0000;
    try
      pcb^ := TStream(dwCookie).Read(pBuff^, cb) ;
    except
      result := $FFFF;
    end;
  end; (*EditStreamReader*)
begin
  destination.Lines.BeginUpdate;
  sourceStream := TMemoryStream.Create;
  try
    source.Lines.SaveToStream(sourceStream) ;
    sourceStream.Position := 0;

    destination.MaxLength := destination.MaxLength + sourceStream.Size;

    rtfStream.dwCookie := DWORD(sourceStream) ;
    rtfStream.dwError := $0000;
    rtfStream.pfnCallback := @EditStreamReader;
    destination.Perform(
      EM_STREAMIN,
      SFF_SELECTION or SF_RTF or SFF_PLAINRTF, LPARAM(@rtfStream)
    ) ;
    if rtfStream.dwError <> $0000 thenb
      raise Exception.Create('Error appending RTF data.') ;
  finally
    sourceStream.Free;
    destination.Lines.EndUpdate;
  end;
end;

Open in new window

Avatar of rfwoolf
rfwoolf
Flag of South Africa image

Sorry I can't be of much help, but would using trim() function work at removing the linebreak?
Avatar of Ferruccio Accalai
Why don't you try the TRichEdit.SelText procedure?

Richedit1.SelText := RichEdit2.Text;

This insert the text at the caretpos

Add the following line

destination.Lines.Delete(destination.Lines.IndexOf(''));

before

source.Lines.SaveToStream(sourceStream) ;

so the full procedure is:

procedure AppendToRichEdit(const source, destination : TRichEdit) ;
var
  rtfStream: TEditStream;
  sourceStream : TMemoryStream;

  function EditStreamReader(
    dwCookie: DWORD;
    pBuff: Pointer;
    cb: LongInt;
    pcb: PLongInt): DWORD; stdcall;
  begin
    result := $0000;
    try
      pcb^ := TStream(dwCookie).Read(pBuff^, cb) ;
    except
      result := $FFFF;
    end;
  end; (*EditStreamReader*)
begin
  destination.Lines.BeginUpdate;
  sourceStream := TMemoryStream.Create;
  try
    destination.Lines.Delete(destination.Lines.IndexOf(''));
    source.Lines.SaveToStream(sourceStream) ;
    sourceStream.Position := 0;

    destination.MaxLength := destination.MaxLength + sourceStream.Size;

    rtfStream.dwCookie := DWORD(sourceStream) ;
    rtfStream.dwError := $0000;
    rtfStream.pfnCallback := @EditStreamReader;
    destination.Perform(
      EM_STREAMIN,
      SFF_SELECTION or SF_RTF or SFF_PLAINRTF, LPARAM(@rtfStream)
    ) ;
    if rtfStream.dwError <> $0000 then
      raise Exception.Create('Error appending RTF data.') ;
  finally
    sourceStream.Free;
    destination.Lines.EndUpdate;
  end;
end;

Open in new window

Avatar of gurkal
gurkal

Use this.
procedure AppendToRichEdit(const source, destination : TRichEdit) ;
var
  rtfStream: TEditStream;
  sourceStream : TStringStream;
  S:String;

  function EditStreamReader(
    dwCookie: DWORD;
    pBuff: Pointer;
    cb: LongInt;
    pcb: PLongInt): DWORD; stdcall;
  begin
    result := $0000;
    try
      pcb^ := TStream(dwCookie).Read(pBuff^, cb) ;
    except
      result := $FFFF;
    end;
  end; (*EditStreamReader*)
begin
  destination.Lines.BeginUpdate;
  Source.Text:=Trim(source.Text);
  sourceStream := TStringStream.Create('');
  try
    source.Lines.SaveToStream(sourceStream) ;
    S:=StringReplace(sourceStream.DataString,'\par }',' }',[]);
  finally
   sourceStream.Free;
  end;

  sourceStream := TStringStream.Create(S);
  try
    sourceStream.Position := 0;

    destination.MaxLength := destination.MaxLength + sourceStream.Size;

    rtfStream.dwCookie := DWORD(sourceStream) ;
    rtfStream.dwError := $0000;
    rtfStream.pfnCallback := @EditStreamReader;
    destination.Perform(
      EM_STREAMIN,
      SFF_SELECTION or SF_RTF or SFF_PLAINRTF, LPARAM(@rtfStream)
    ) ;
    if rtfStream.dwError <> $0000 then
      raise Exception.Create('Error appending RTF data.') ;
  finally
    sourceStream.Free;
    destination.Lines.EndUpdate;
  end;
end;

Open in new window

Avatar of SteveFarndon2000

ASKER

Thanks for your contributions.

Gurkal : I tried your version and it did eliminate the extra carriage-return effect, but it did still introduced an extra space character at the end of the inserted string. Needs something more. I note that the 'source' TRichEdit seems to always force its text to have an extra character at the very end (looks like a space) - maybe that's what's causing it?

Mahdi78: Your suggestion gives me the same results as before. Don't understand.

Note that I'm using Delphi 2006 under WinXP.



Hello,

I mean insert destination.Lines.Delete(destination.Lines.IndexOf('')); before source.Lines.SaveToStream(sourceStream) ;

Now, replace destination.Lines.Delete(destination.Lines.IndexOf('')); by source.Text := TrimRight(source.Text);

so the full procedure is:
if not the case explain more your problem
SOLUTION
Avatar of Mahdi78
Mahdi78
Flag of Algeria image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks Guys. Just want to acknowledge your comments. Need a bit more time to check your answers.
Been pulled out over the lst few weeks. Still nee to test your answers. Plan to get back onto this case in a couple of weeks. I do need an answer so I will be back. Thanks guys.
This question has been classified as abandoned and is being closed as part of the Cleanup Program.  See my comment at the end of the question for more details.