Reading RTF from memory

I want to read an RTF format text from memory and display it in RichEdit, without using RichEdit1.Lines.LoadFrom file

I try to add the text manually using Lines property but it didn't display it as a Rrich Edit format

Thanks, Motaz
LVL 7
MotazAsked:
Who is Participating?
 
sarcConnect With a Mentor Commented:
Hi!
I think the easiest solution is really using streaming... See - the LoadFromFile part is nothing than a "LoadFromFileStream"-part.
If you found the sourcecode in the example of kretzschmar too long - just try this small part - it converts your string into a stream and writes it into the richedit1 control:

procedure MyForm.WriteToRichEdit ( s : string );
var
  stream : TMemoryStream;
begin
  Stream:=TMemoryStream.Create;
  Stream.WriteBuffer(Pointer(S)^, Length(S));
  Stream.Position:=0;
  richedit1.lines.LoadFromStream(Stream);
  Stream.Free;
end;

greetz
Carsten
0
 
EpsylonCommented:
I think the only possibility is:

RichEdit1.Lines.LoadFromStream


Eps.
0
 
MotazAuthor Commented:
I have no experince in using streams, so that suppose that I have a rich edit text in a Memo lines such as:

\rtf1\ansi\deff0\deftab720{\fonttbl
{\f0\fswiss MS Sans
Serif;}{\f1\froman\fcharset2
Symbol;}{\f2\fswiss\fprq2
System;}{\f3\fswiss\fcharset1
Arial;}{\f4\fswiss Arial;}{\f5\fscript
Mistral;}{\f6\fswiss Arial;}}
{\colortbl\red0\green0\blue0;\red2
55\green0\blue0;\red255\green0\b
lue255;\red0\green0\blue255;}
\deflang1033\pard\qc\plain\f6\fs3
2\cf2\b Rich Edit Control
Overview\plain\f4\fs32\cf1\b
\par \plain\f4\fs16\cf0\b (from
Win32SDK Help)
\par \pard\plain\f4\fs20\cf0
\par
\pard\li500\ri840\fi-20\plain\f5\fs3
0\cf0 A rich edit control is a window
in which the user can enter and edit
text. The text can be assigned
character and paragraph formatting,
and can include embedded OLE
objects. Rich edit controls provide a

How can I display this text with rich edit format in a RichEdit1??

Motaz
0
Cloud Class® Course: CompTIA Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

 
EpsylonCommented:
Normally you can do this:

RichEdit1.Lines.Assign(Memo1.Lines);

but that won't apply the formatting attributes...
0
 
MotazAuthor Commented:
Thats my problem..
I want to apply the formatting attributes

MOtaz
0
 
kretzschmarCommented:
hi motaz,

a sample form my paq, which should show, how to use editstream-api function to insert and render an rtf memorystream content

the sample contains both methods
- stream rtf-text out to a stream  (Flag SFF_SELECTION, only selection)
- stream rtf-text in from a stream (Flag SFF_SELECTION, replace selection

if SFF_SELECTION not set the whole RTF-text will applied

all different formattings will be copied
no memory limitations (except physical)

a sample, not excact wahat you need, because as RTF-Source i use a file, but this you van simple replace

unit riched_u;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ComCtrls, richedit;  //richedit is used

type
  TForm1 = class(TForm)
    RichEdit1: TRichEdit;
    Button1: TButton;
    OpenDialog1: TOpenDialog;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;


Function MyEditStreamCallBackOut(dwCookie: Longint; pbBuff: PByte;  //Not used here
                              cb: Longint; var pcb: Longint): Longint; stdCall;

Function MyEditStreamCallBackIn(dwCookie: Longint; pbBuff: PByte;
                              cb: Longint; var pcb: Longint): Longint; stdCall;

var
  Form1: TForm1;

implementation

{$R *.DFM}

var
  EditStream : TEditStream;  //from richedit.pas
  ms : TMemoryStream;  // the working stream
  L : Longint;  //only temporary hold the portions of transfer

Function MyEditStreamCallBackOut(dwCookie: Longint; pbBuff: PByte;
                              cb: Longint; var pcb: Longint): Longint; stdCall;
Begin
  ms.WriteBuffer(pbbuff^,cb);
  pcb := DWord(@L);
  result := cb;
end;

Function MyEditStreamCallBackIn(dwCookie: Longint; pbBuff: PByte;
                                cb: Longint; var pcb: Pointer): Longint; stdcall;
var
  dw : DWord;
Begin
  pcb := @cb;
  if cb > ms.Size - ms.position then
    dw := ms.Size - ms.position
  else
    dw := cb;
  if dw <> 0 then
    ms.ReadBuffer(pbbuff^,dw);
  result := 0;
  dw := ms.position;
  move(dw,pcb,sizeof(dw));
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if opendialog1.execute then
  begin
    ms.LoadFromFile(opendialog1.filename);
    ms.Position := 0;
    editStream.dwCookie := SF_RTF or SFF_SELECTION;
    editStream.dwError := 0;
    editStream.pfnCallback := @MyEditStreamCallBackIn;
    Richedit1.Perform(EM_StreamIn,SF_RTF or SFF_SELECTION,DWord(@EditStream));

   {The Other direction (from a richedit to a stream), but the vcl support is easier

  editStream.dwCookie := SF_RTF;
  editStream.dwError := 0;
  editStream.pfnCallback := @MyEditStreamCallBackOut;
  Richedit1.Perform(EM_StreamOut,SF_RTF,DWord(@EditStream));

                       }
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ms := TMemoryStream.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  ms.Free;
end;

end.

let me know, if you have problems with this

meikl
0
 
MotazAuthor Commented:
Thanks meikl
I need a very simple solution, using for example MemoryStream or a like, because I'm afraid of that functions that I didn't know may affect my application, because now it is become very complicated.

Motaz
0
 
bryan7Commented:
this q. is similar to one I once made, but it doesn't yet work.. hi meikl.. you promised to take a look at it long time ago.. please.. could you ? I'll post a 150p. A graded if you can fix that. thanks
0
 
kretzschmarCommented:
hi bryan,

i've a bad conscience about this, because i've forgotten you :-(

well a s far as i know, was the problem you have the inserts from rtf-lines into a richedit, which causes a streaming error, right?

guessing its a timing problem.

yup, can you send me (again?) the problem and the enviroment-options you use to meikl@spektracom.de

meikl

ps.: you need not post a q for me, because i've said i look at this, then i should do it.
0
 
mscatenaCommented:
You can send a message to the RTF control like that:

var
  Buffer: PChar;
begin
  . . .
  RichEdit1.Perform(EM_STREAMIN, SF_RTF, longint(Buffer));
end;
0
 
MotazAuthor Commented:
mscatena, it raises acccess violation,

Did I need only the procedure you mentioned? No need for all the callback procedures which miekl mentioned?

Motaz
0
 
sarcCommented:
Hups... I forgot - if you need the other way too...

function MyForm.GetRichEditStream : string;
var
  Size   : Integer;
  Stream : TMemoryStream;
begin
  Stream:=TMemoryStream.Create;
  RichEdit1.Lines.SaveToStream(Stream);
  Size := Stream.Size - Stream.Position;
  SetString(Result, nil, Size);
  Stream.Read(Pointer(Result)^, Size);
  Stream.Free;
end;

greetz
Carsten
0
 
MotazAuthor Commented:
Thanks sarc it is very brief and usifull solution.

Motaz
www.geocities.com/motaz1
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.