如何实现IE自动填表
简介:IE的面板实际就是嵌入到IE浏览器中的子窗体。面板有两种显示模式,一种是垂直显示在浏览器的左侧,一种是水平显示在浏览器的下方。IE浏览器内置提供了很多的标准面板,如收藏夹和搜索面板这些是垂直的面板,而每日提示和讨论面板则是水平的面板。
此外我们还可以通过实现COM组件来添加我们自己的浏览器面板到IE中。当我们的面板COM组件注册后,它会被添加到浏览器的查看菜单的浏览器栏的子菜单下。当用户选中该菜单项后,该面板就会显示在浏览器中。
实现面板COM组件:接下来我们将实现类似于IE内置的收藏夹的一个面板,不过它不是用来收藏网址的,而是用来运行程序的。下面是它的示意图:
同所有的COM组件一样,面板组件首先要实现IUnknown和IClassFactory接口,不过Borl and提供了TComObject类,这个类已经实现了前面两个接口,我们因此就不需要再重造轮子了,只要从TComObject类继承就可以了。
首先选择菜单File|New|ActiveX|Com Object命令,创建一个TDelphiBand的COM组件框架
然后我们就需要实现IDeskBand,IObjectWithSite和IPersistStreamInit或者IPersi stStream接口了。其中IPersistStreamInit和IPersistStream接口可以用来保存面板的各种状态和信息,IPersistStreamInit和IPersistStream接口相比就是多了一个Init New的方法,这个方法可以用来初始化面板组件的状态。在本文中,由于不涉及信息的保存,因此这个接口的方法的实现大部分都是直接返回E_NOTIMPL表示该方法没有被实现。除了GetClassID方法,当系统调用这个方法的时候,我们需要返回COM组件的GUID标识符。
function TDelphiBand.GetClassID(out classID:TCLSID):HResult;
begin
classID:=CLSID_DelphiBand;
Result:=S_OK;
end;
IObjectWithSite接口,顾名思义这个接口就是一个嵌入在COM容器中的组件需要实现的接口,当用户选中一个浏览器面板的时候,IE这个COM容器会调用面板组件的IObjectW ithSite的SetSite方法,这个方法传递过来的punkSite参数就是COM容器的IUnknown 接口,通过这个接口我们可以获得IE提供的各个COM接口,进而可以调用IE提供的所有功能。这个方法的一般实现是:
1、如果方法传过来的punkSite参数为nil,表示面板组件正在被隐藏释放。这时方法
的返回结果必须为S_OK。
2、如果punkSite参数不为nil,则通过punkSite获得我们所需要的COM接口(如IE
的IWebBrowser接口),并将其保存起来。
下面是SetSite方法的实现代码:
function TDelphiBand.SetSite(const pUnkSite:IUnknown):HResult;
begin
if Assigned(pUnkSite)then begin
你到底爱上谁//获得IInputObjectSite接口,并保存起来,后面会用它通知浏览器
//面板焦点的变化情况
Site:=pUnkSite as IInputObjectSite;赵丽颖把皇冠戴反
//通过调用GetWindow来获得父窗体的句柄,并保存
(pUnkSite as IOleWindow).GetWindow(ParentWnd);
//获得IE的IWebBrowser2接口
(Site as IServiceProvider).QueryService(IWebbrowserApp,IWebbrowser2,I E);
end;
Result:=S_OK;
end;
IObjectWithSite还有一个GetSite方法也需要实现,方法的定义如下:
function GetSite(const riid:TIID;out site:IUnknown):HResult;stdcall;
其中我们需要返回在SetSite方法中保存的Site接口,然后从site接口获得riid参数所需要的接口,如果Site接口为nil,方法的返回的HResult需要设定为E_Fail,表示调用失败。如果Site接口支持riid指定的接口的话,我们就返回S_OK表示成功,如果S ite接口不为nil,但是也不支持riid的接口的话,我们就返回E_NOINTERFACE,表示无法获得riid对应的接口。代码实现如下:
function TDelphiBand.GetSite(const riid:TIID;out site:IUnknown):HResult; begin
if Assigned(Site)then Result:=Site.QueryInterface(riid,site) else Result:=E_FAIL;
end;
接下来的IDeskBand接口就是我们面板组件所要实现的核心接口了。它包括下面这些方法。
function GetBandInfo(dwBandID,dwViewMode:DWORD;var pdbi:TDeskBandI nfo):HResult;stdcall;
function ShowDW(fShow:BOOL):HResult;stdcall;
function CloseDW(dwReserved:DWORD):HResult;stdcall;
function ResizeBorderDW(var prcBorder:TRect;punkToolbarSite:IUnknow n;
顶极厨师fReserved:BOOL):HResult;stdcall;
function GetWindow(out wnd:HWnd):HResult;stdcall;
function ContextSensitiveHelp(fEnterMode:BOOL):HResult;stdcall;
其中ContextSensitiveHelp方法是用来提供上下文帮助支持的,未来简单起见,这里我们不提供上下文支持,所以简单返回E_NOTIMPL就可以了。而ResizeBorderDW方法系统也从来不会调用,因此我们也返回E_NOTIMPL。
获得面板的显示信息
对于GetWindow方法来说,我们需要返回要嵌入到IE中的子窗体的句柄,以便容器用来显示。下面是GetWindow方法的实现:
function TDelphiBand.GetWindow(out wnd:HWnd):HResult;
begin
//如果还没有创建面板窗体,则创建
if not Assigned(BandForm)then
begin
//父窗体是先前在SetSite方法中获得的父窗体
BandForm:=TBandForm.CreateParented(ParentWnd);
//将IE赋值给
面板界面的相应变量
BandForm.IE:=IE;
End;
//返回子窗体的句柄
Wnd:=Bandform.Handle;
SavedWndProc:=Bandform.WindowProc;
//替换默认的窗体消息过程
Bandform.WindowProc:=BandWndProc;
Result:=S_OK;
end;
此外,因为面板对象是以子窗体的形式显示,它还必须实现窗口消息过程。这里我们使用BandWndProc过程替换了窗体默认的消息处理过程,BandWndProc的实现如下:procedure TDelphiBand.BandWndProc(var Message:TMessage);
begin
//当我们的窗体的子控件,如编辑框获得焦点后,系统会发WM_ParentNotify消息给//我们的窗体,这时要通知浏览器我们面板获得了焦点,这样IE才会将快捷键发送给//我们的窗体
if(Message.Msg=WM_PARENTNOTIFY)then三支一扶报考条件
begin
Hasfocus:=True;
FocusChange(True);
end;
//然后调用保存的原有窗体消息过程来处理
SavedWndProc(Message);
end;
FocuseChanged方法用来通知浏览器焦点的变化情况,实现如下:
procedure TDelphiBand.FocusChange(bHasFocus:Boolean);
begin
//调用先前保存的IInputObjectSite的OnFocusChangeIS方法通知浏览器
//焦点变化。
if(Site<>nil)then Site.OnFocusChangeIS(Self,bHasFocus);
end;
系统获得子窗体的同时,因为IE本身对子窗体的显示区域是有一定限制的,所以它还需要知道面板窗体的某些属性,如最大显示尺寸、最小显示尺寸、改变大小时的尺寸变化幅度等信息,这些信息它是通过调用面板组件的IDeskBand接口的GetBandInfo方法来获得的。下面是GetBandInfo方法的声明:
function GetBandInfo(dwBandID,dwViewMode:DWORD;var pdbi:TDeskBandInfo):HR esult;
其中dwBandID参数是面板的标识符,这个标识符是COM容器赋予的,我们需要保
存这个ID。dwViewMode表示面板的显示模式:
DBIF_VIEWMODE_FLOATING
浮动面板
DBIF_VIEWMODE_NORMAL
水平面板
DBIF_VIEWMODE_TRANSPARENT
联通光纤猫面板是透明的
DBIF_VIEWMODE_VERTICAL
面板是垂直面板
pdbi参数则是一个TDESKBANDINFO结构,结构定义如下:
DESKBANDINFO=packed record
dwMask:DWORD;
ptMinSize:TPointL;
车险必上险种
ptMaxSize:TPointL;
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论