您的位置:首页 > 编程语言 > Delphi

[Delphi] 编写IE菜单扩展

2011-10-14 23:45 417 查看
编写IE菜单扩展

介绍

向IE中添加的自定义菜单,可以被用来执行可执行文件,脚本语言和COM对象的方法,对于前两种执行方式,相对比较简单,只需要对注册表进行编程就可以了,但是能够执行的功能非常有限,而使用COM组件扩展IE菜单则相对复杂,但是能够执行的功能也相对是最强大的,所以下面我就主要介绍基于COM的菜单扩展方式,还要注意的一点是只有IE5及以后的版本才支持菜单的扩展。

创建COM组件

对于一个IE菜单项COM组件来说,它最少需要实现IOleCommandTargetCOM接口,如果COM组件还想要对当前IE中显示的页面进行操作的话,就还需要实现IObjectWithSite接口,对于IObjectWithSite接口,我将在后面的工具条按钮扩展中讨论它的实现。

首先在Delphi中用New|Other命令调出NewItems对话框,然后在ActiveX页面中选择创建一个新的ActiveXLibrary,将项目保存为IEMenu.dpr,然后再次调用New|Other|ActiveX命令,新建一个名为TIEHelloWorld的ComObject对象,然后添加IOleCommandTarget接口的方法实现,完成的类的定义如下:

type

TIEHelloWorld=class(TComObject,IOleCommandTarget)

protected

//IOleCommandTarget方法接口

functionQueryStatus(CmdGroup:PGUID;cCmds:Cardinal;

prgCmds:POleCmd;CmdText:POleCmdText):HResult;stdcall;

functionExec(CmdGroup:PGUID;nCmdID,nCmdexecopt:DWORD;

constvaIn:OleVariant;varvaOut:OleVariant):HResult;stdcall;

end;

IOleCommandTarget包含
QueryStatus
Exec
两个方法,其中文档上说QueryStatus方法会被IE调用来获得当前菜单的状态,我们需要返回OLECMDF_ENABLED或者其它值来表示是否允许点击,但是在实际当中,我发现IE从来没有调用过我的菜单扩展的QueryStatus方法,不过不管怎么说,还是按正常的来实现。

functionTIEHelloWorld.QueryStatus(CmdGroup:PGUID;cCmds:Cardinal;

prgCmds:POleCmd;CmdText:POleCmdText):HResult;

begin

//允许点击菜单

prgCmds^.cmdf:=OLECMDF_ENABLED;

Result:=S_OK;

end;

当用户点击菜单后,IE会调用IOleCommandTarget接口的Exec方法来执行用户自定义的操作。

functionTIEHelloWorld.Exec(CmdGroup:PGUID;nCmdID,nCmdexecopt:DWORD;

constvaIn:OleVariant;varvaOut:OleVariant):HResult;

begin

Result:=S_OK;

//nCmdI为0时,表示菜单和工具条按钮被点击了

try

ShowMessage('HelloIE');

except

Result:=E_FAIL;

end;

//注意下面
的话语句会导致AV,不知道为什么?[/code]
//vaOut:=Null;

end;

Exec方法带有很多参数,其中IE在调用菜单扩展和工具条按钮扩展组件的的Exec方法时,会设定nCmdI为0,其它参数对于我们来说,都不需要关心,只要在成功执行代码后,返回S_OK,在失败时返回E_Fail就可以了。实现了IOleCommandTarget接口之后,一个最简单的IE菜单扩展就完成了。

注册组件

要想让IE在启动后能够发现菜单扩展COM组件,并加载菜单进行显示,需要在注册表中填写一些配置信息。

1、要在HKEY_LOCAL_MACHINE\Software\Microsoft\InternetExplorer\Extensions\项目下新建一个关键字,名为菜单扩展的Guid的字符串形式。

2、然后在新建的HKEY_LOCAL_MACHINE\Software\Microsoft\InternetExplorer\Extensions\<菜单扩展Guid>关键字下再创建一个名为ClsidExtension的项目,值也为扩展的Guid。

3、然后在HKEY_LOCAL_MACHINE\Software\Microsoft\InternetExplorer\Extensions\<菜单扩展Guid>关键字下添加名为MenuText的字符串字段,写入IE用来显示菜单扩展的菜单项标题文本。

4、我们还可以创建一个MenuStatusBar,IE会在鼠标停留在我们的扩展对应的菜单项时,在IE的状态条上显示MenuStatusBar的文本。这个注册表项不是必须项目,可以省略。

5、通常情况下,IE会在工具菜单下显示我们的扩展菜单,但是我们也可以创建一个MenuCustomize字段,设定其值为help。这时IE会将我们的菜单放到帮助主菜单下面。如果我们的菜单扩展是用来向IE中添加上下文帮助的,可以设定这个选项。这个注册表项同样也是可以忽略的。

注意:如果将注册表位置由HKEY_LOCAL_MACHINE改成HKEY_CURRENT_USER,则菜单扩展会对所有该机器上用户生效。

为了实现添加必要的注册表信息,编写AddMenuItem方法来实现注册功能:

//添加IE菜单

procedureAddMenuItem(MenuText,StatusBarText,Guid:

string;HelpMenu:Boolean);

var

Reg:TRegistry;

begin

Reg:=TRegistry.Create;

withRegdo

begin

RootKey:=HKEY_LOCAL_MACHINE;

OpenKey('\Software\Microsoft\InternetExplorer\Extensions\'+Guid,True);

ifHelpMenuthen

WriteString('MenuCostumize','help');

WriteString('CLSID','{1FBA04EE-3024-11d2-8F1F-0000F87ABD16}');

WriteString('MenuText',MenuText);

WriteString('MenuStatusBar',StatusBarText);

WriteString('ClsidExtension',Guid);

CloseKey;

CloseKey;

Free;

end;

end;

同时我们还要注销菜单扩展的功能,方法
RemoveMenuItem
被用来删除注册表项,删除注册表项是
Guid
来进行的,因为
Guid
是可以保证唯一性


//删除IE菜单

procedureRemoveMenuItem(Guid:string);

var

Reg:TRegistry;

begin

Reg:=TRegistry.Create;

withRegdo

begin

RootKey:=HKEY_LOCAL_MACHINE;

DeleteKey('\Software\Microsoft\InternetExplorer\Extensions\'+Guid);

free;

end;

end
;


最后,我们定义TIEHelloMenuFactory的TComObjectFactory派生类来调用上面的方法实现COM的组件的注册和注销:

type

TIEHelloMenuFactory=class(TComObjectFactory)

public

procedureUpdateRegistry(Register:Boolean);override;

end;


{TIEHelloMenuFactory}


procedureTIEHelloMenuFactory.UpdateRegistry(Register:Boolean);

begin

inherited;

ifRegisterthen

//添加到Tools菜单下

AddMenuItem('HelloIE','HelloIEMenuItem',GuidToString(ClassID),False)

else

//Todo:通过Guid进行删除

RemoveMenuItem(GuidToString(ClassID));

end;


initialization

TIEHelloMenuFactory.Create(ComServer,TIEHelloWorld,Class_IEHelloWorld,

'IEHelloWorld','',ciMultiInstance,tmApartment);

end.

完成程序后,我们可以在DelphiIDE中使用菜单Run|RegisterActiveXServer和UnRegisterActiveXServer来注册创建好的菜单扩展,然后启动IE,运行后的效果示意图:



总结

上面我们介绍了如何创建一个最简单的菜单扩展,接下来我将探讨IE扩展的一些更为高级的技术。

转自Delphi深度探索
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: