Solved

Delphi: converting rtf to plain text

Posted on 2014-10-10
9
1,301 Views
Last Modified: 2014-10-13
I have some rtf stored in a database. At times, I only need the text and not the rft formatting. Here's the approach I tried to convert the rtf to plain text:

procedure TChronNoteMenu.GetText;
  var
    rtfEdit: TRichEdit;
    ss: TStringStream;
begin
  sText := ''; // class level public variable to contain the text
  ...
  sText := [Get rtf from database];
  // I have verified that sText at this point contains the expected rtf text
  if bPlainText then begin
    rtfEdit := TRichEdit.Create(nil);
    ss := TStringStream.Create;
    try
      ss.WriteString(sText);
      // ***** WHEN EXECUTING, FOLLOWING LINE CAUSES ERROR *****
      rtfEdit.Lines.LoadFromStream(ss); 
      sText := rtfEdit.Text;
    finally
      rtfEdit.free;
      ss.Free;
    end;
  end;
  ...
end;

Open in new window


Does it matter here that the rtf is not divided into lines but is just a blob of rtf? If so how do I load it correctly?
Actual error message: EInvalidOperation: TPopupList Control has no parent window.
I'm not sure if this message is actually a result of this error or the result of something that fails later because of the failure here. Thanks in advance for your help.
0
Comment
Question by:EricTaylor
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 2
9 Comments
 
LVL 14

Assisted Solution

by:SteveBay
SteveBay earned 500 total points
ID: 40373716
I believe that your TRichEdit  depends upon a parent window to do it's work.

rtfEdit := TRichEdit.Create(Form1);
rtfEdit.Parent := Form1;
0
 

Author Comment

by:EricTaylor
ID: 40373950
Thanks Steve. That seems to solve half the problem. (At least, hope it's half.) My code now looks like this:
procedure TChronNoteMenu.GetText;
  var
    rtfEdit: TRichEdit;
    ss: TStringStream;
begin
  sText := ''; // class level public variable to contain the text
  ...
  sText := [Get rtf from database];
  // I have verified that sText at this point contains the expected rtf text
  if bPlainText then begin
    rtfEdit := TRichEdit.CreateParented(application.MainFormHandle);
    rtfEdit.Visible := false;
    ss := TStringStream.Create;
    try
      ss.WriteString(sText);
      //   *****  AT THIS POINT, SS APPEARS TO HAVE NO CONTENT  *****
      //   *****  SO I GET EMPTY RESULT EVERY TIME   ***** 
      rtfEdit.Lines.LoadFromStream(ss);
      rtfEdit.PlainText := true;
      sText := rtfEdit.Text;
    finally
      rtfEdit.free;
      ss.Free;
    end;
  end;
  cdsFilterClear(cdsTextBlocks);
end;

Open in new window

0
 

Author Comment

by:EricTaylor
ID: 40373955
oops... hit post too soon. So at this point, it doesn't appear that my rtf is loading to the stream... so I'm consistently getting an empty result. (But checked with the debugger and sText definitely has rtf content going in.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:EricTaylor
ID: 40374091
I appeared to have been wrong about where the problem was above ss.DataString does in fact show the appropriate rtf. So I'm suspecting that there is something wrong with sText := rtfEdit.Text;
0
 
LVL 19

Expert Comment

by:Thommy
ID: 40376667
I once did it like that using a memory stream...

sText:= sql.FieldByName('rtf').AsAnsiString;

//Write to a memory stream
aStream := TMemoryStream.Create;
aStream.Clear;
aStream.Write(PAnsiChar(sText)^, Length(sText));
aStream.Position := 0;

//Load stream into RichEdit
RichEdit1.PlainText := False;
RichEdit1.Lines.LoadFromStream(aStream);
stream.Free;

//Save as plain text
RichEdit1.PlainText:=true;
sText:=RichEdit1.Text;

Open in new window

0
 

Author Comment

by:EricTaylor
ID: 40377691
I have tried two versions of getting text from rtf, one with a TStringStream and one with a TMemoryStream. In both cases, sText ends up empty.
procedure TChronNoteMenu.GetText;
  var
    rtfEdit: TRichEdit;
    ss: TStringStream;
begin
  sText := '';
  sRtf := '';
  ...
  sRtf := cdsTextBlocks.FieldByName('MacroText').AsString;
  // IN HAVE CONFIRMED THAT sRTF DOES CONTAIN THE RTF TEXT AS EXPECTED
  rtfEdit := TRichEdit.CreateParented(application.MainFormHandle);
  rtfEdit.Visible := false;
  ss := TStringStream.Create;
  try
    ss.WriteString(sRtf);
    showmessage(ss.DataString);
    // THE ABOVE CORRECTLY SHOWS THE FULL RTF
    rtfEdit.Lines.LoadFromStream(ss);
    rtfEdit.PlainText := true;
    sText := rtfEdit.Text;
    // sText IS ALWAYS EMPTY AT THIS POINT
    ....

Open in new window


procedure TChronNoteMenu.GetText;
  var
    rtfEdit: TRichEdit;
    aStream: TMemoryStream;
begin
  sText := '';
  sRtf := '';
  ...
  sRtf := cdsTextBlocks.FieldByName('MacroText').AsString;
  // IN HAVE CONFIRMED THAT sRTF DOES CONTAIN THE RTF TEXT AS EXPECTED
  rtfEdit := TRichEdit.CreateParented(application.MainFormHandle);
  rtfEdit.Visible := false;
  aStream := TMemoryStream.Create;
  try
    aStream.Write(PAnsiChar(sRtf)^, Length(sRtf));
    rtfEdit.Lines.LoadFromStream(aStream);
    rtfEdit.PlainText := true;
    sText := rtfEdit.Text;
    showmessage(sText);
    // sText IS SIMILARLY EMPTY HERE
    ....

Open in new window

0
 
LVL 14

Accepted Solution

by:
SteveBay earned 500 total points
ID: 40377724
Hmm... Could it be as simple as resetting the position of your stream?

    aStream.Write(PAnsiChar(sRtf)^, Length(sRtf));
    aStream.Position := 0; // << reset stream position
    rtfEdit.Lines.LoadFromStream(aStream);
0
 

Author Comment

by:EricTaylor
ID: 40377736
might be. I'll try that. Working with streams is really new to me, so on this front, I'm a hacker...
0
 

Author Closing Comment

by:EricTaylor
ID: 40378465
Thanks Steve. And thanks to you too Thommy... though I couldn't get yours to quite work. (I think because I wasn't using TMemoryStream quite correctly; I found working the the TStringStream easier in this case. Much appreciate the help.
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
select query - oracle 16 101
can't find the executable in Simulator 1 113
Firemonkey webbrowser scrollbars ? 1 57
can i put an image from resource into image tag ? 6 32
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…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…

730 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