MRB
MRB

Reputation: 452

Delphi and Internet Explorer, create "global" IE

I have some inherited code for opening IE, this is short version :

procedure OpenIE(URL: OleVariant; FieldValues: string = '');
var ie : IWebBrowser2;
begin
  ie := CreateOleObject('InternetExplorer.Application') as IWebBrowser2;
  ie.Navigate2(URL, Flags, TargetFrameName, PostData, Headers);
  ShowWindow(ie.HWND, SW_SHOWMAXIMIZED);
  ie.Visible := true;
  ...
end;

Since CreateOleObject takes a long time to execute I would like to have one "prepared" IE for the first run.

For example in Main FormCreate to call CreateOleObject, then for 1st call of OpenIE to use "IE" object already created.

For 2nd, 3rd ... call of OpenIE - just usual call ie := CreateOleObject

When I try to code it, I get some threads and marshaling errors, I am newbie in this area. What would be proper way to do this (some small code example would be great) ?

Thanks in advance.

Upvotes: 1

Views: 3811

Answers (1)

David Heffernan
David Heffernan

Reputation: 612954

Perhaps you are creating the browser instance in a different thread from which you then issue subsequent calls. The following trivial code works exactly as expected:

type
  TMainForm = class(TForm)
    ShowBrowser: TButton;
    procedure FormCreate(Sender: TObject);
    procedure ShowBrowserClick(Sender: TObject);
  private
    FBrowser: Variant;
  end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
  FBrowser := CreateOleObject('InternetExplorer.Application');
end;

procedure TMainForm.ShowBrowserClick(Sender: TObject);
begin
  FBrowser.Navigate('http://stackoverflow.com');
  ShowWindow(FBrowser.HWND, SW_SHOWMAXIMIZED);
  FBrowser.Visible := True;
end;

I'm not using IWebBrowser2 because I don't have the import unit handy. But that won't change anything – your problems will not be related to early/late binding.

Obviously FormCreate runs in the GUI thread. And ShowBrowserClick is a button OnClick event handler. And so it runs in the main GUI thread.

If you are calling your OpenIE function from a thread other than the GUI thread, that would explain your errors. If you access the browser on a thread other than the one on which it was created, you will receive an EOleSysError with message The application called an interface that was marshalled for a different thread.

Finally, a word of advice when asking questions. If you receive an error message, make sure you include that exact error message in your question. Doing so makes it much more likely we can provide good answers.

Upvotes: 7

Related Questions