Solved

Delphi: converting rtf to plain text

Posted on 2014-10-10
9
1,113 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
  • 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
 

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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
This Micro Tutorial will give you a basic overview how to record your screen with Microsoft Expression Encoder. This program is still free and open for the public to download. This will be demonstrated using Microsoft Expression Encoder 4.
Windows 10 is mostly good. However the one thing that annoys me is how many clicks you have to do to dial a VPN connection. You have to go to settings from the start menu, (2 clicks), Network and Internet (1 click), Click VPN (another click) then fi…

920 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

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now