跨线程操作com

今天重新学习多线程,发生了很多问题,按照这个时间,我应该是在睡午觉的时候了。-_-~!

跨线程操作Com 或者叫 Delphi 多线程 WebBrowser出错,又可以叫作 Delphi 多线程 IhtmlDocument2 赋值出错、多线程操作网页元素提示错误,百度一下还有很多这类的问题,其它统称“跨线程操作com”。我写这么多,是为了给像我这样的新手找到这篇文章,更快地掌握它。

编程遇到问题的时候真的很无助,没有人教程你,只能自己百度来百度去,不断的累积知识,推敲。

转载一章文章:http://www.cnblogs.com/MaxWoods/archive/2006/08/07/469970.html 我也是在这篇文章得到启发!

/*

原因很简单,因为WebBrowse是COM组件,而COM组件的初始化需要和COM组件的运行代码在同一线程内,如果是跨线程调用COM组件,则会发生内存错误,
因为在另一线程的COM接口并没有实例
解决办法:
1.在同一线程内使用初始化和COM接口
2.复制COM接口到另一线程(比较麻烦,请自行查阅资料)
3.通过Windows消息来调用COM接口(MFC里面就常用这一招,比如CListCtrl调用的是Windows的ListView的COM,而CListCtrl在内部通过Windows消息来进行控制)*/ 转自:http://bbs.csdn.net/topics/270014712

我的实验代码:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, OleCtrls, SHDocVw, MSHTML, ActiveX;

type
  TForm1 = class(TForm)
    wb1: TWebBrowser;
    btn1: TButton;
    mmo1: TMemo;
    procedure btn1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  MarshalStream: Pointer;

implementation

{$R *.dfm}

function myfun:Cardinal;stdcall;
  var
    doc:IHTMLDocument3;
begin
  CoInitialize(nil);
  CoGetInterfaceAndReleaseStream(IStream(MarshalStream),IID_IHTMLDocument3,doc);
  Form1.mmo1.Text := doc.documentElement.outerHTML;
  CoUninitialize;
end;

procedure TForm1.btn1Click(Sender: TObject);
  var
    id:DWORD;
    doc:IHTMLDocument3;
begin
  doc := form1.wb1.document as ihtmldocument3;
  CoMarshalInterThreadInterfaceInStream(IID_IHTMLDocument3,doc,IStream(MarshalStream));
  CreateThread(nil,0,@myfun,nil,0,id);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  wb1.Navigate('http://www.baidu.com/);
end;

end.

posted @ 2012-11-22 12:46  stma  阅读(694)  评论(0)    收藏  举报