Delphi中挂接IWebBrowser2的自动化事件
2016-07-27 18:18
351 查看
![](http://simg.sinajs.cn/blog7style/images/common/sg_trans.gif)
转载▼
标签:delphiit | 分类: 软件设计 |
IEnumConnections = interface
['{B196B287-BAB4-101A-B69C-00AA00341D07}']
function Next(celt: Longint; out elt;
pceltFetched: PLongint): HResult; stdcall;
function Skip(celt: Longint): HResult; stdcall;
function Reset: HResult; stdcall;
function Clone(out Enum: IEnumConnections): HResult; stdcall;
end;
{ IConnectionPoint interface }
{$EXTERNALSYM IConnectionPoint}
IConnectionPoint = interface
['{B196B286-BAB4-101A-B69C-00AA00341D07}']
function GetConnectionInterface(out iid: TIID): HResult; stdcall;
function GetConnectionPointContainer(out cpc: IConnectionPointContainer): HResult;
stdcall;
function Advise(const unkSink: IUnknown; out dwCookie: Longint): HResult; stdcall;
function Unadvise(dwCookie: Longint): HResult; stdcall;
function EnumConnections(out Enum: IEnumConnections): HResult; stdcall;
end;
{ IConnectionPointContainer interface }
{$EXTERNALSYM IConnectionPointContainer}
IConnectionPointContainer = interface
['{B196B284-BAB4-101A-B69C-00AA00341D07}']
function EnumConnectionPoints(out Enum: IEnumConnectionPoints): HResult;
stdcall;
function FindConnectionPoint(const iid: TIID;
out cp: IConnectionPoint): HResult; stdcall;
end;
{ IEnumConnectionPoints interface }
{$EXTERNALSYM IEnumConnectionPoints}
IEnumConnectionPoints = interface
['{B196B285-BAB4-101A-B69C-00AA00341D07}']
function Next(celt: Longint; out elt;
pceltFetched: PLongint): HResult; stdcall;
function Skip(celt: Longint): HResult; stdcall;
function Reset: HResult; stdcall;
function Clone(out Enum: IEnumConnectionPoints): HResult;
stdcall;
end;
需要接收自动化事件通知时,可以用InterfaceConnect注册:
procedure InterfaceConnect(const Source: IUnknown; const IID: TGUID;
const Sink: IUnknown; var Connection: Longint);
var
CPC: IConnectionPointContainer;
CP: IConnectionPoint;
begin
Connection := 0;
if Source.QueryInterface(IConnectionPointContainer, CPC)=S_OK then
if CPC.FindConnectionPoint(IID, CP)=S_OK then
CP.Advise(Sink, Connection);
end;
其中Source为受控方OLE对象的接口。IID是事件连接点的GUID。一个OLE对象可能有多个事件连接点,比如IWebBrowser2有个事件连接点为:
WebBrowserEventId : TGUID='{34A715A0-6587-11D0-924A-0020AFC7AC4D}';
Sink就是接收事件通知的对象的接口了,这个对象至少需要实现IUnknown和IDispatch接口。当事件触发时,事件接收者的Invoke方法会被调用:
function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;Flags: Word; var Params;
VarResult, ExcepInfo, ArgErr: Pointer): HResult; virtual; stdcall;
DispID为事件的编号,可以从自动化对象的事件接口的声明里找到这个编号。比如IWebBrowser的事件声明
DWebBrowserEvents2 = dispinterface
['{34A715A0-6587-11D0-924A-0020AFC7AC4D}']
procedure StatusTextChange(const Text: WideString); dispid 102;
procedure ProgressChange(Progress: Integer; ProgressMax: Integer); dispid 108;
procedure CommandStateChange(Command: Integer; Enable: WordBool); dispid 105;
procedure DownloadBegin; dispid 106;
procedure DownloadComplete; dispid 104;
procedure TitleChange(const Text: WideString); dispid 113;
procedure PropertyChange(const szProperty: WideString); dispid 112;
procedure BeforeNavigate2(const pDisp: IDispatch; var URL: OleVariant; var Flags: OleVariant;
var TargetFrameName: OleVariant; var PostData: OleVariant;
var Headers: OleVariant; var Cancel: WordBool); dispid 250;
procedure NewWindow2(var ppDisp: IDispatch; var Cancel: WordBool); dispid 251;
procedure NavigateComplete2(const pDisp: IDispatch; var URL: OleVariant); dispid 252;
procedure DocumentComplete(const pDisp: IDispatch; var URL: OleVariant); dispid 259;
procedure OnQuit; dispid 253;
procedure OnVisible(Visible: WordBool); dispid 254;
procedure OnToolBar(ToolBar: WordBool); dispid 255;
procedure OnMenuBar(MenuBar: WordBool); dispid 256;
procedure OnStatusBar(StatusBar: WordBool); dispid 257;
procedure OnFullScreen(FullScreen: WordBool); dispid 258;
procedure OnTheaterMode(TheaterMode: WordBool); dispid 260;
end;
方法声明后面dispid数字就是DispID。所以如果接收到IWebBrowser2的DispID为259的通知,就表明DocumentComplete事件发生了。
Invoke的Params变参包含特定事件的附加信息,或者叫做事件参数。他是一个TDispParams结构:
tagDISPPARAMS = record
rgvarg: PVariantArgList;//Variant类型的数组。
rgdispidNamedArgs: PDispIDList;
cArgs: Longint; //参数个数
cNamedArgs: Longint;
end;
对于IWebBrowser2的DocumentComplelte事件,rgvarg[1]就是发出此事件通知的IWebBrowser2接口。请注意,一个内嵌框架下载完成也会触发DocumentComplelte事件,要判断是否整个网页都下载完毕了可以用以下方法(TEventDispatch是我写的一个接收自动化事件通知的类):
function TEventDispatch.Invoke(DispID: Integer; const IID: TGUID;
LocaleID: Integer; Flags: Word; var Params;
VarResult, ExcepInfo, ArgErr: Pointer): HResult;
var
vPDispParams: PDispParams;
ib:IWebBrowser2;
begin
vPDispParams := PDispParams(@Params);
if DispID=259 then
begin
if (IDispatch(OleVariant(vPDispParams.rgvarg[1])).QueryInterface(IID_IWebBrowser2,ib)=0) and (ib.Container=nil) then
begin
function TEventDispatch.Invoke(DispID: Integer; const IID: TGUID;
LocaleID: Integer; Flags: Word; var Params;
VarResult, ExcepInfo, ArgErr: Pointer): HResult;
var
vPDispParams: PDispParams;
ib:IWebBrowser2;
begin
vPDispParams := PDispParams(@Params);
if DispID=259 then
begin
if (IDispatch(OleVariant(vPDispParams.rgvarg[1])).QueryInterface(IID_IWebBrowser2,ib)=0) and (ib.Container=nil) then
begin
//整个网页下载完成
end
else
begin
//某个内嵌框架网页下载完成了,但是整个网页没有完成
end;
end;
Result:= S_OK;
end;
本文来自Delphi之窗,原文地址:http://www.52delphi.com/list.asp?ID=1208
相关文章推荐
- Delphi 一种简单的二进制校验方法,适用于简单的权限管理或开关控制
- delphi vclskin与MDI子窗体冲突--美化mainmenu与子窗体BorderIcons冲突
- Delphi~通过程序窗体句柄获取程序路径
- Delphi Thread
- 用Delphi+GLScene轻松打造3D场景、动画之GLScene基础
- Delphi 属性多参数使用
- typhon例子:cs,bufDataset(类似delphi的clientDataset),josn解析器
- delphi ini 文件读取
- delphi模态窗口跑到后面的解决办法
- Delphi 使窗体Showmodal后可以操作其他窗体
- Delphi 停靠技术的应用2(窗体之间的相互停靠,引入宿主窗体)
- Delphi 停靠技术的应用1(在一个窗体中停靠另一个窗体)
- Delphi指针详解
- Delphi多线程处理
- DELPHI存储过程调用
- Delphi 快捷键
- Delphi异常处理的基本原则和方法
- Delphi 窗体失踪在最上面的代码
- Delphi如何实现多国语言
- Delphi 目前使用delay函数功能