跨线程操作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.