问题
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.
回答1:
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.
来源:https://stackoverflow.com/questions/12817277/delphi-and-internet-explorer-create-global-ie