Solved

Reading RTF from memory

Posted on 2000-04-03
13
358 Views
Last Modified: 2010-05-18
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
0
Comment
Question by:Motaz
  • 5
  • 2
  • 2
  • +3
13 Comments
 
LVL 13

Expert Comment

by:Epsylon
ID: 2682762
I think the only possibility is:

RichEdit1.Lines.LoadFromStream


Eps.
0
 
LVL 7

Author Comment

by:Motaz
ID: 2682766
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
 
LVL 13

Expert Comment

by:Epsylon
ID: 2682808
Normally you can do this:

RichEdit1.Lines.Assign(Memo1.Lines);

but that won't apply the formatting attributes...
0
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 7

Author Comment

by:Motaz
ID: 2683013
Thats my problem..
I want to apply the formatting attributes

MOtaz
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 2683059
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
 
LVL 7

Author Comment

by:Motaz
ID: 2683110
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
 
LVL 3

Expert Comment

by:bryan7
ID: 2683741
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
 
LVL 27

Expert Comment

by:kretzschmar
ID: 2683802
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
 
LVL 1

Expert Comment

by:mscatena
ID: 2686163
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
 
LVL 7

Author Comment

by:Motaz
ID: 2686488
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
 

Accepted Solution

by:
sarc earned 50 total points
ID: 2690196
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
 

Expert Comment

by:sarc
ID: 2690234
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
 
LVL 7

Author Comment

by:Motaz
ID: 2692574
Thanks sarc it is very brief and usifull solution.

Motaz
www.geocities.com/motaz1
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question