[Delphi]如何挂上IDocHostUIHandler接口实现?
来源:互联网 发布:移动网络进电信服务器 编辑:程序博客网 时间:2024/04/29 10:25
为了更好地控制WebBrowser,我们可以在一个com对象中实现IDocHostUIHandler(和IDocHostUIHandler2)接口,并把这个接口实现挂到WebBrowser实例上去,成功挂接之后,我们就可以通过实现这些接口的com对象控制WebBrowser的行为方式及其外观了。
为了演示如何挂接COM对象,我们假设我们在窗体上放置了一个TWebBrowser实例WB,并且实例化了一个实现IDocHostUIHandler接口的对象IEObject。我们将分别演示通过TWebBrowser的ICustomDoc接口和IOleObject实现挂接。
1. 使用IOleObject接口
TWebBrowser对象在初始化时会向宿主查询其是否实现了IDocHostUIHandler接口,假如宿主实现了该接口的话,就会调用该接口的方法控制自己的行为和外观。因此我们只要在TWebBrowser初始化之前将实现IDocHostUIHandler的com对象注册为TWebBrower对象的宿主的话,就可以让TWebBrowser控件自身来查询IDocHostUIHandler接口了。
{code start}
procedure TMainForm.FormCreate(Sender: TObject);
var
Rect: TRect;
begin
//设置浏览器站点,设置之后浏览器将自动查询IDocHostUIHandler、IDocHostUIHandler2、
//IDocHostShowUI等接口
(WB.Application as IOleObject).SetClientSite(IEObject as IOleClientSite);
//本地激活浏览器控件
Rect := Self.GetClientRect;
(WB.Application as IOleObject).DoVerb(OLEIVERB_INPLACEACTIVATE, nil,
Self, 0, Self.Handle, Rect);
ManageConnection(True); //注册事件连接
WB.GoHome; //程序启动时导航到首页
end;
{code end}
2. 使用ICustomDoc接口
如果IEObject由于某种原因无法实现IOleClientSite的话,我们就不能简单地让TWebBrowser对象来查询其宿主的IDocHostUIHandler接口,我们必须显式地将实现该接口的对象赋给TWebBrowser的Document对象,ICustomDoc可以说就是为了这个目的而生的。
使用该方法的一个至关重要的问题是必须在TWebBrowser的Document对象建立的时候才可以调用其ICustomDoc接口,否则就会挂接失败,由于Navigate方法是异步执行的,因此我们不能像这样挂接:
{code start}
WB.GoHome; //or WB.Navigate('http://xxx");
(WB.Document as ICustomDoc).SetUIHandler(IEObject);
{code end}
这种挂接方式可能会生效,但是SetUIHiandler完全可能在Document对象建立之前就被调用,因此这不是一个好的途径,我们可以在TWebBrowser的OnDocumentComplete处理函数中进行挂接,这时候我们可以确保TWebBrowser的Document对象确确实实已经建立起来了,因此调用理论上讲可以100%成功。
除此之外,我们还可以这样做:
{code start}
WB.GoHome;
while (WB.ReadState <> READYSTATE_COMPLETE )
;
(WB.Document as ICustomDoc).SetUIHandler(IEObject);
{code end}
这样做同样可以达到我们的目的。缺点: 虽然这种方法可以达到挂接的目的,但是在实践中发现,由于WB是在装载文档完成之后才挂上IDocUIHandler接口实现的,因此第一次转载文档的时候是不会使用该接口来控制外观和行为的(没挂上当然就不知道怎么用了),因此必须在挂上之后再一次进行刷新才行。
附:由于Delphi本身缺少IDocHostUIHandler等接口的声明,如果要编译上述代码,你可以去IE&Delphi下载IEConst.pas。其中ICustomDoc接口声明不存在于该文件中,特声明如下:
{code start}
ICustomDoc = interface(IUnknown)
['{3050F3F0-98B5-11CF-BB82-00AA00BDCE0B}']
function SetUIHandler(const pUIHandler: IDocHostUIHandler): HRESULT; stdcall;
end;
{code end}
为了演示如何挂接COM对象,我们假设我们在窗体上放置了一个TWebBrowser实例WB,并且实例化了一个实现IDocHostUIHandler接口的对象IEObject。我们将分别演示通过TWebBrowser的ICustomDoc接口和IOleObject实现挂接。
1. 使用IOleObject接口
TWebBrowser对象在初始化时会向宿主查询其是否实现了IDocHostUIHandler接口,假如宿主实现了该接口的话,就会调用该接口的方法控制自己的行为和外观。因此我们只要在TWebBrowser初始化之前将实现IDocHostUIHandler的com对象注册为TWebBrower对象的宿主的话,就可以让TWebBrowser控件自身来查询IDocHostUIHandler接口了。
{code start}
procedure TMainForm.FormCreate(Sender: TObject);
var
Rect: TRect;
begin
//设置浏览器站点,设置之后浏览器将自动查询IDocHostUIHandler、IDocHostUIHandler2、
//IDocHostShowUI等接口
(WB.Application as IOleObject).SetClientSite(IEObject as IOleClientSite);
//本地激活浏览器控件
Rect := Self.GetClientRect;
(WB.Application as IOleObject).DoVerb(OLEIVERB_INPLACEACTIVATE, nil,
Self, 0, Self.Handle, Rect);
ManageConnection(True); //注册事件连接
WB.GoHome; //程序启动时导航到首页
end;
{code end}
2. 使用ICustomDoc接口
如果IEObject由于某种原因无法实现IOleClientSite的话,我们就不能简单地让TWebBrowser对象来查询其宿主的IDocHostUIHandler接口,我们必须显式地将实现该接口的对象赋给TWebBrowser的Document对象,ICustomDoc可以说就是为了这个目的而生的。
使用该方法的一个至关重要的问题是必须在TWebBrowser的Document对象建立的时候才可以调用其ICustomDoc接口,否则就会挂接失败,由于Navigate方法是异步执行的,因此我们不能像这样挂接:
{code start}
WB.GoHome; //or WB.Navigate('http://xxx");
(WB.Document as ICustomDoc).SetUIHandler(IEObject);
{code end}
这种挂接方式可能会生效,但是SetUIHiandler完全可能在Document对象建立之前就被调用,因此这不是一个好的途径,我们可以在TWebBrowser的OnDocumentComplete处理函数中进行挂接,这时候我们可以确保TWebBrowser的Document对象确确实实已经建立起来了,因此调用理论上讲可以100%成功。
除此之外,我们还可以这样做:
{code start}
WB.GoHome;
while (WB.ReadState <> READYSTATE_COMPLETE )
;
(WB.Document as ICustomDoc).SetUIHandler(IEObject);
{code end}
这样做同样可以达到我们的目的。缺点: 虽然这种方法可以达到挂接的目的,但是在实践中发现,由于WB是在装载文档完成之后才挂上IDocUIHandler接口实现的,因此第一次转载文档的时候是不会使用该接口来控制外观和行为的(没挂上当然就不知道怎么用了),因此必须在挂上之后再一次进行刷新才行。
附:由于Delphi本身缺少IDocHostUIHandler等接口的声明,如果要编译上述代码,你可以去IE&Delphi下载IEConst.pas。其中ICustomDoc接口声明不存在于该文件中,特声明如下:
{code start}
ICustomDoc = interface(IUnknown)
['{3050F3F0-98B5-11CF-BB82-00AA00BDCE0B}']
function SetUIHandler(const pUIHandler: IDocHostUIHandler): HRESULT; stdcall;
end;
{code end}
- [Delphi]如何挂上IDocHostUIHandler接口实现?
- Delphi中TWebBrowser的使用,实现IDocHostUIHandler接口
- IDocHostUIHandler接口探索
- IDocHostUIHandler
- C++(MFC)中WebBrowser去除3D边框的方法(实现IDocHostUIHandler接口)
- Delphi接口的底层实现
- Delphi接口的底层实现
- Delphi接口的底层实现
- Delphi接口的底层实现
- Delphi接口的底层实现
- Delphi接口的底层实现
- Delphi接口的底层实现
- IDocHostUIHandler::ShowContextMenu添加自定义菜单的另类实现
- IDocHostUIHandler::ShowContextMenu添加自定义菜单的另类实现
- 如何用delphi实现短信同步接口
- delphi中IDispath接口的实现类
- Delphi如何实现内存共享
- Delphi 给窗体上面所有的控件都挂上一个事件处理过程华软源码
- Transforms CTM 转换矩阵
- Android 内容提供器Content Providers(一)
- PHP二分法的实现(ip地址定位)
- FLEX 笔记--组件的行为和动画效果
- oracle 10g正则表达式 REGEXP_LIKE 用法
- [Delphi]如何挂上IDocHostUIHandler接口实现?
- C++虚函数表解析
- 在shell中使用echo命令输出带颜色的文本
- 枚举、联合
- QuarZ例子
- DataTable,IList中排除重复项
- 把apk文件加载android虚拟机上面
- 在pictureBox中拖动图片的实现代码
- DataGrid GridView 隔行换色 鼠标经过改变背景色