Page 2 of 2

Posted: Thu Jan 08, 2015 11:17 am
by Sergey Tkachenko
I cannot compile your project because I do not have cxWebBrowser installed.
The crash problem may be because of calling rvHelper.RichView.Reformat.

Change the lines

Code: Select all

            lRVHelper.RichView.Reformat;
            lRVHelper.RichView.SelectAll;
            lRVHelper.RichView.CopyRVF;
            FRichView.PasteRVF;
To

Code: Select all

var Stream: TMemoryStream;

...
Stream := TMemoryStream.Create;
try
  lRVHelper.RichView.SaveRVFFromStream(Stream, False);
  Stream.Position := 0;
  FRichView.InsertRVFFromStreamEd(Stream);
finally
  Stream.Free;
end;
But, as I said before, WebBrowser is not needed at all.
If you want to support different character sets, just make all text Unicode.

For example, in your project, I changed:

Code: Select all

procedure TForm1.FormCreate(Sender: TObject);
begin
  // leaving only one text and one paragraph style, and making them Unicode
  FRichView.Style := TRVStyle.Create(Self);
  FRichView.Style.TextStyles.Clear;
  FRichView.Style.ParaStyles.Clear;
  FRichView.Style.TextStyles.Add.Unicode := True; // <-- requires document clearing
  FRichView.Style.ParaStyles.Add;
  FRichView.Clear;
  FRichView.Format;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  HTMLViewer: THtmlViewer;
  HTMLViewImporter: TRVHTMLViewImporter;
  lRVHelper: ThaRVReportHelper;
begin
  lRVHelper := NewRVReportHelper(nil);
  lRVHelper.MailDir := GetMailFolder;
  HTMLViewer := THtmlViewer.Create(Self);
  HTMLViewer.Parent := Self;
  HTMLViewer.LoadFromFile(ExtractFilePath(Application.ExeName)+'a.html');
  HTMLViewImporter := TRVHTMLViewImporter.Create(Self);
  HTMLViewImporter.ImportHtmlViewer(HTMLViewer, FRichView);
  FRichView.Format;
  HTMLViewImporter.Free;
  HTMLViewer.Free;
end;
After that, I can see German characters in the imported text when compiling this project in Delphi 7, although my default system language is not German but Russian.

In this code, I loaded HTML directly in FRichView. You can use an intermediate RVReportHelper, as before, but copy documents using TMemoryStream instead of the Clipboard.

Suggestions to improve:
1) Call NormalizeRichView after ImportHTMLViewer
2) Create a simple image cache while loading, to prevent downloading the same image again and again (for example, your HTML file contains 99 trans.gif). You can see how it is implemented in RichViewActions (see RichViewActions.pas, FDownloadedPictures)

Posted: Thu Jan 08, 2015 12:55 pm
by Lucian
If you still want to see the AV.... TcxWebBrowser, it is a simple in-house wrapper, you can replace it with TWebBrowser (in the dfm than pas), compile and run, click the button and you will have the AV.

In any case, I tested some of you changes and, yes, it works much better. I still get an AV, this time is different and is not consistent, it may be something in my test case.

However, and this is very important, since you don't use the clipboard, I noticed that you are using HTMLViewer.LoadFromFile instead of my original HTMLViewImporter.LoadFromClipboard (you missed some code regarding the picture, I fixed that so I can get the pics also - and yes, in the application I have a cache :-))

Basically, you prefer to use HTMLViewer instead of the HTMLViewImporter and the result is much better. In one word, does that this mean the HTMLViewImporter "sucks" and I should stay away of it?

Lastly ... how do I use "NormalizeRichView", I can't find this method anywhere.

Posted: Thu Jan 08, 2015 2:37 pm
by Sergey Tkachenko
1) HTMLViewImporter is still used in my code. HTML is loaded in HTMLViewer, then HTMLViewImporter copies document from HTMLViewer to FRichView.

In this new code, HTML is loaded in HTMLViewer from a file, not from the Clipboard, this is the only difference.

2) NormalizeRichView is included in RVNormalize.pas in RichViewActions. I suggest using it even if you do not use RichViewActions. Call: NormalizeRichView(FRichView.RVData)

3) I'll try with replacing to TWebBrowser tomorrow. In my test, after replacing to the code without using clipboard, there were no crashes.

About RichViewActions

Posted: Fri Jan 09, 2015 9:10 am
by Lucian
Hi Sergey,

To add this last feature in our application (read/edit html emails) we added a lot of third party code ... kind of we are not very happy with the outcome. In any case, about using RichViewActions and the call to NormalizeRichView, is it mandatory or just a suggestion? Any problem if we don't use RichViewActions? This seems to have a ton of code and we would prefer not using it, unless there is no other way.

regards
Lucian

Posted: Fri Jan 09, 2015 9:25 am
by Lucian
One other thing, the WebBrowser component IS needed, because that's what we want to use to display the orginal html email. It is MS native and it displays the email perfectly, exactly as they were sent from example from Outlook or other email programs.

So I am hoping you can fix whatever that crash is when loading from clipboard.

Thanks
Lucian

Posted: Tue Jan 13, 2015 7:06 am
by Sergey Tkachenko
Sorry for the delay.

1. You can use a web browser to show HTML, but it is not necessary to use it to load HTML in TRichViewEdit.

2. The bug is in the image caching. You cannot insert the same graphic class twice in TRichView, because it will be freed multiple times.

In haRVTools.pas, change

Code: Select all

Graphic := TGraphic(Images.Objects[Index])
to

Code: Select all

  begin
    Graphic := RVGraphicHandler.CreateGraphic(TGraphicClass(TGraphic(Images.Objects[Index]).ClassType));
    Graphic.Assign(TGraphic(Images.Objects[Index]));
    end

Great!

Posted: Tue Jan 13, 2015 7:15 am
by Lucian
Nice, thank you very much!
Regards,
Lucian

Posted: Wed Jan 21, 2015 9:46 am
by Lucian
Hi Sergey,

The code you indicated above (Button1Click) has one little quirk. Using the THtmlViewer component has the undesirable effect of showing this control for a small duration of time, depending on how large it is the html being processed.

Is there a way to import html in TRichViewEdit, without using THtmlViewer component? In my case the html will come from a blob in the database, I would use streams and not temporary files.

regards

Posted: Wed Jan 21, 2015 11:54 am
by Sergey Tkachenko
Assign HTMLViewer.Visible=False just after creating it.

There is another HTML importing component, TrvHtmlImporter, but it supports only basic HTML formatting.