1

我有一些用于打开 IE 的继承代码,这是简短版本:

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;

由于 CreateOleObject 需要很长时间才能执行,我希望为第一次运行准备一个“准备好的”IE。

例如在 Main FormCreate 中调用 CreateOleObject,然后在第一次调用 OpenIE 时使用已经创建的“IE”对象。

对于 OpenIE 的第 2 次、第 3 次...调用 - 只是通常的调用 ie := CreateOleObject

当我尝试对其进行编码时,我得到了一些线程和编组错误,我是这个领域的新手。什么是正确的方法(一些小代码示例会很棒)?

提前致谢。

4

1 回答 1

7

也许您正在另一个线程中创建浏览器实例,然后您从该线程发出后续调用。以下琐碎的代码完全按预期工作:

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;

我没有使用IWebBrowser2,因为我手边没有导入单元。但这不会改变任何事情——你的问题不会与早/晚绑定有关。

显然FormCreate是在 GUI 线程中运行的。并且ShowBrowserClick是一个按钮OnClick事件处理程序。所以它在主 GUI 线程中运行。

如果您OpenIE从 GUI 线程以外的线程调用您的函数,这将解释您的错误。如果您在创建浏览器的线程之外的线程上访问浏览器,您将收到一条EOleSysErrorwith 消息The application called an interface that was marshalled for a different thread

最后,提问时的忠告。如果您收到错误消息,请确保在您的问题中包含该确切的错误消息。这样做使我们更有可能提供好的答案。

于 2012-10-10T10:45:17.457 回答