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 を 1 つ用意したいと考えています。

たとえば、Main FormCreate で CreateOleObject を呼び出してから、OpenIE の最初の呼び出しで、既に作成されている「IE」オブジェクトを使用します。

2 番目、3 番目の ... OpenIE の呼び出し - 通常の呼び出し 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 スレッドで実行されます。AndShowBrowserClickはボタンOnClickイベント ハンドラです。したがって、メインの GUI スレッドで実行されます。

OpenIEGUI スレッド以外のスレッドから関数を呼び出すと、エラーが説明されます。ブラウザが作成されたスレッドとは別のスレッドでブラウザにアクセスすると、 The application called an interface that was marshalled for a different thread というEOleSysErrorメッセージが表示されます。

最後に、質問する際のアドバイスを一言。エラー メッセージが表示された場合は、その正確なエラー メッセージを質問に含めてください。そうすることで、適切な回答を提供できる可能性が高くなります。

于 2012-10-10T10:45:17.457 に答える