Solved

Delphi: converting rtf to plain text

Posted on 2014-10-10
9
1,173 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
Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

 

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

Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
PDF library for Delphi 2 120
FMX StringGrid1->Canvas->FillRect Problem 3 150
Create a path if not exists 7 76
Need Help Delphi 2010 CheckBox1 Stored value in memo 13 66
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…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Microsoft Active Directory, the widely used IT infrastructure, is known for its high risk of credential theft. The best way to test your Active Directory’s vulnerabilities to pass-the-ticket, pass-the-hash, privilege escalation, and malware attacks …
Email security requires an ever evolving service that stays up to date with counter-evolving threats. The Email Laundry perform Research and Development to ensure their email security service evolves faster than cyber criminals. We apply our Threat…

785 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