用C++Builder实现IE快捷菜单

Author: 庞巍伟 Date: 2001年 30期

?牐犛霉齆etAnts的朋友都知道,它会在IE的右键快捷菜单中加入“Download All By NetAnts”的项目,点一下它,NetAnts就会得到当前网页的所有链接,方便用户快速下载文件。这是怎么做的呢?
  ?牐犚饩稣飧鑫侍猓颐窍瘸橄蟪鑫侍獾氖抵剩?
  ?牐?1?犜贗E的快捷菜单中加入自己的项目。
  ?牐?2?犑垢孟钅恐赶蜃约旱某绦颍⒔械牧唇印⒘唇用枋龅刃畔⒆魑问莞约旱某绦颉?
  ?牐牰杂诘谝徊嚼此担薷墓⒉岜淼呐笥讯寄芮嵋资迪帧J紫却蚩⒉岜肀嗉鳎╮egedit.exe),在HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt键下,你可以看到 Download &All By NetAnts 的子键(如果安装了NetAnts的话),其中“&”符号后面的字母标识了快捷键的按键。
  ?牐犜诟米蛹陆鲇辛礁黾担ㄈ鏭30020504a^),其中“默认”表示菜单所指向的文件,“Contexts”则表示你添加的菜单项目在什么情况下出现。我们注意到,NetAnts指向的是NAGetAll.htm文件,根据笔者研究发现,它不可以指向EXE文件,就算指向EXE文件,IE也不会启动它。Contexts的值是243,表示除了在文本框的快捷菜单以外的菜单中都出现NetAnts的菜单;如果是255,则表示任何情况下都出现;如果是12的话,则只在文本框的快捷菜单中才出现。
  ?牐牸热恢赶虻氖莌tm文件,那么如何启动NetAnts,又如何传递参数呢?我们先打开NaGetAll.htm文件,可以看到如下代码:
  ?牐?<script language=“VBScript”>
  ?牐燨n Error Resume Next
  ?牐爏et NetAntsApi = CreateObject(“NetAnts.API”)//创建NetAnts对象
  ?牐爄f err<>0 then
  ?牐燗lert(“NetAnts not properly installed on this PC)”??
  ?牐爀lse
  ?牐爏et links = external.menuArguments.document.links//得到网页所有连接的集合
  ?牐燫eDim params(links.length*2)//links.length为所有连接的个数
  ?牐爌arams(0)=external.menuArguments.document.Url//得到当前页面的Url
  ?牐爁or i = 0 to links.length-1
  ?牐爌arams(i*2+1)=links(i).href//连接地地址
  ?牐爌arams(i*2+2)=links(i).innerText//连接的描述
  ?牐爊ext
  ?牐燦etAntsApi.AddUrlList params
  ?牐爀nd if
  ?牐?</script>
  ?牐犜词且欢蜼BScript,并且调用了NetAnts对象,至此问题的关键所在已经知道了,就是要创建一个自己的COM对象。创建COM对象不太容易,但用VB,Delphi这样的快速开发工具倒也不难。下面笔者就用C++ Builder为例来创建一个COM对象完成上述功能。
  ?牐犉舳疌++ Builder创建一个新的工程,在Form1中加入一个ListBox组件,用于显示加入的连接地址。在该工程下新建一个Automation Object,输入GetUrl,其余保持不变,按OK钮,这样C++ Builder将为你创建一系列文件用于描述COM结构,我们所要做的就是添加接口和方法。
  ?牐犜贗GetUrl接口中加入AddHrefList方法,并且添加一个Variant*类型的参数pList,设置返回值为HRESULT,
  ?牐犎缓蟮惆此⑿掳磁ィ珻++ Builder会自动刷新所需文件。在工程管理器中打开GetUrlImpl.cpp文件,会看到刚才接口的实现函数的声明,添加如下代码,并保存工程。
  ?牐燰ariant* vp=(Variant*)pList; //转换为Variant类,在此转换成SafeArray*也可,但麻烦一些
  ?牐爄nt di=vp->ArrayDimCount(); //得到数组的维数
  ?牐爄f (di>1)??
  ?牐爎eturn 0;??
  ?牐爄nt hb=vp->ArrayHighBound();//得到数组的上下标
  ?牐爄nt lb=vp->ArrayLowBound?煟牔?
  ?牐爁or (int n=lb;n<=hb;n++)??
  ?牐牓焮
  ?牐燰ariant vi=vp->GetElement(n);//得到数组的元素
  ?牐燬tring ai=String(vi);?牔?
  ?牐燜orm1->ListBox1->Items->Add(ai);?牔?
  ?牐牓爙
  ?牐爎eturn 1??
  ?牐犗衷冢桓鲎远韵笠丫唇ㄍ瓿伞1嘁朐诵谐绦颉>驮谙低持凶远⒉崃死啵约袄嗟乃薪涌凇=酉吕淳秃芗虻チ耍凑誑aGetAll.htm文件的形式写一个VBScript,如下:
  ?牐?<script language=“VBScript”>
  ?牐燨n Error Resume Next
  ?牐爏et OB = CreateObject( “Project1.GetUrl” )??
  ?牐爄f err<>0 then
  ?牐燗lert(“必要的类没有注册!”)??
  ?牐爀lse
  ?牐爏et links = external.menuArguments.document.links
  ?牐燫eDim params(links.length)??
  ?牐爌arams(0)=external.menuArguments.document.Url
  ?牐爁or i = 0 to links.length-1
  ?牐爌arams(i+1)=links(i).href
  ?牐爊ext
  ?牐燨B.AddHrefList params
  ?牐燗lert(“你成功了!”)??
  ?牐爀nd if
  ?牐?</script>
  ?牐牪⑶以谧⒉岜碇屑尤肟冀驳哪茄募担械墓ぷ骶妥鐾炅恕2还感牡亩琳呋岱⑾稚鲜龃胗隢aGetAll.htm还是有一点出入,主要就在最后的Alert(“我成功了!”)上,这是为了解决对象生存期的问题,为了解决这个问题,需要将COM对象单独写在一个Dll中,其实NetAnts也是这样做的。