Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

Delphi: converting rtf to plain text

Posted on 2014-10-10
9
Medium Priority
?
1,841 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 2000 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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 

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 2000 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

Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

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…
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Whether it be Exchange Server Crash Issues, Dirty Shutdown Errors or Failed to mount error, Stellar Phoenix Mailbox Exchange Recovery has always got your back. With the help of its easy to understand user interface and 3 simple steps recovery proced…
As many of you are aware about Scanpst.exe utility which is owned by Microsoft itself to repair inaccessible or damaged PST files, but the question is do you really think Scanpst.exe is capable to repair all sorts of PST related corruption issues?
Suggested Courses
Course of the Month13 days, 7 hours left to enroll

578 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