views:

481

answers:

2

Mercifully brief for once, from me - hopefully the title says it all. I have some unicode .html files that I want to display inside a THtmlViewer component, in Delphi.

I can't seem to persuade the code to work just doing '.LoadFromFile' - do I firstly need to load the unicode file into a stream and then somehow convert it?

Delphi 2007, THtmlViewer v9.45

I've not done anything with unicode files, or THtmlViewer, before so apologies in advance if this is a really dumb question!

+1  A: 

Okay, well here's the guts of what I came up. Constructive criticism and observations appreciated!

// load either an ansi or unicode-type html doc into the browser component.
// the filename has already been confirmed as an existing file
procedure TfrmBrowser.LoadDocument(FFileName:string);
var
  FWideText : Widestring;
  FAnsiText : AnsiString;
  FRequiredLen : Integer;
  FFileStream : TFileStream;
  FMemStream : TMemoryStream;
  FBuffer : Byte;
begin
  FFileStream := TFileStream.Create(FFileName, fmOpenRead or fmShareDenyNone);
  // anything less than half a dozen bytes would be pointless, but...
  if FFileStream.Size>1 then
  begin
    // checking the first byte of the file to give us a clue about file-type
    FFileStream.Read(FBuffer,1);
    FFileStream.Position:=0;  // rewind position
    if (FBuffer=$FF) or (FBuffer=$EF) then
    begin
      // probably Unicode
      FRequiredLen := FFileStream.Size div 2;  // 2 bytes per char
      SetLength(FWideText, FRequiredLen);
      FFileStream.Read(FWideText[1], FFileStream.Size);
      // cast it into an Ansistring
      FAnsiText := FWideText;
      FMemStream := TMemoryStream.Create;
      FMemStream.Write(FAnsiText[1], FRequiredLen);
      FMemStream.Position := 0; // rewind the position
      // load the stream into the THtmlViewer
      vwBrowse.LoadFromStream(FMemStream);  
      FMemStream.Free;
    end
    else
    begin
      // probably Ansi, just load original filestream in
      vwBrowse.LoadFromStream(FFileStream);
    end;
    FFileStream.Free;
  end;

Obviously missing some error-trapping, but that's the basic idea.

robsoft
A: 

You are using Delphi 2007. That's before the beginning of Unicode era in Delphi Programming!

Although it is very tiresome to make Unicode work in early versions of Delphi, it is quite possible to attain a satisfactory result in some controls, especially the THtmlView component.

I post some code example from one of my programs:

//code to toggle source or WYSIWYG views
var
  htmEd: IHTMLDocument2;
begin
  htmEd := HtmlEdit.Document as IHtmlDocument2;
  if ToggleTabSet.TabIndex = 0 then
  begin
    HtmlEditContainer.PageIndex := 0; // Tab sheet index
    htmEd.body.innerHTML := Memo1.Lines.Text; // TTntMemo
    pnlEditorState.Caption := 'Design View';
  end
  else
    if ToggleTabSet.TabIndex = 1 then
    begin
      HtmlEditContainer.PageIndex := 1;
      Memo1.Lines.Text := HtmEd.body.innerHTML;
      pnlEditorState.Caption := 'Source View';
    end;

Reading the above code you can see that I'm using a TTntMemo component to which the html file is loaded first. I'm then loading the 'Text' of the memo to HtmlView's 'body.innerHTML' property.

htmEd.body.innerHTML := Memo1.Lines.Text;

Note:

  1. TntWare's 'Memo1.Lines.Text;' is WideString type.
  2. 'IHTMLDocument2' comes from TEmbeddedWB. See reasons for why TEmbeddedWB is good?

That is what worked for me in early days. I have switched to Delphi 2009, and things are much easier now (just setting suitable TEncoding while loading files)!

Olaf
Thanks Olaf, that's interesting. I hadn't seen the TTntMemo (etc), or TEmbeddedWB before. They both look interesting, although at the moment I've managed to get something working under THTMLViewer and using that solution has also given me a lot more control over printing (dialog-free printing of the browser view as a metafile to PDF etc) - I was having a nightmare controlling printed output in a satificatory way from TWebBrowser. I will bookmark both components for a closer look when I have time though - many thanks!
robsoft
@robsoft: You are welcome!
Olaf
@robsoft: I was having a nightmare controlling printed output in a satificatory way from TWebBrowser. << Are you using custom made method or the plain old simple 'HtmlEdit.PrintPreView;'? That gives the advantage of ready-made print preview from IE itself!
Olaf
Hi Olaf, sorry didn't see the comment here until now. I'm using the existing stuff in PBear's component at the moment, as this is proof-of-concept work and I'll probably take it as a starting point and develop it (really want something to generate convincingly-similar PDFs from the preview). I couldn't get TWebBrowser to print preview properly (it's an IE thing, not an implementation thing) and in the end the client wanted me to get the preview 'right' - it was a key driver in moving away from TWebBrowser to something that I could 'get at' and control more directly.
robsoft