0

How to set entire HTML in MSHTML?

I am trying using this assignment:

   (Document as IHTMLDocument3).documentElement.innerHTML := 'abc';  

but I got the error:

"Target element invalid for this operation"

I've also tried using

(Document as IHTMLDocument2).write 

but this form only adds HTML into the body section, and I need to replace all the HTML source.
Does somebody have any idea of how I do this?

Thanks in advance.

Douglas Lise
  • 1,466
  • 1
  • 20
  • 46

2 Answers2

1

Here's some of my old code, see if it helps you:

type
  THackMemoryStream = class(TMemoryStream);

procedure Clear(const Document: IHTMLDocument2);
begin
  Document.write(PSafeArray(VarArrayAsPSafeArray(VarArrayOf([WideString('')]))));
  Document.close;
end;

procedure LoadFromStream(const Document: IHTMLDocument2; Stream: TStream);
var
  Persist: IPersistStreamInit;
begin
  Clear(Document);
  Persist := (Document as IDispatch) as IPersistStreamInit;
  OleCheck(Persist.InitNew);
  OleCheck(Persist.Load(TStreamAdapter.Create(Stream)));
end;

procedure SetHtml(const Document: IHTMLDocument2; const Html: WideString);
var
  Stream: TMemoryStream;
begin
  Stream := TMemoryStream.Create;
  try
    THackMemoryStream(Stream).SetPointer(PWideChar(Html), (Length(Html) + 1) * SizeOf(WideChar));
    Stream.Seek(0, soFromBeginning);
    LoadFromStream(Document, Stream);
  finally
    Stream.Free;
  end;
end;
Ondrej Kelle
  • 36,941
  • 2
  • 65
  • 128
  • The correct way to clear the document is to Navigate() to 'about:blank' instead. – Remy Lebeau Mar 24 '10 at 10:11
  • The problem with Navigate is that it's asynchronous so you'd have to remember/replace the appropriate event handler and restore it later which seems kludgy. I admit I haven't tested the above Clear procedure extensively. Is there a problem with it? An alternative might be to load from an empty (or minimal html string) stream. – Ondrej Kelle Mar 24 '10 at 10:22
  • you **MUST** use Navigate() to 'about:blank' at-least once to initialize the document, before using `Clear` (if you are using a TWebBrowser) – kobik Nov 30 '11 at 10:50
  • @kobik Yes, you have to `Navigate` once to a URL, otherwise you wouldn't have a valid reference to `IHTMLDocument2` in the first place. I thought that was obvious. – Ondrej Kelle Nov 30 '11 at 10:53
0

As an alternative you can also use TEmbededWB which is an extended wrapper around a web browser and has some easy to use methods that provide this functionality.

skamradt
  • 15,366
  • 2
  • 36
  • 53