如何像NetAnts那样列举网页联接
发布:siney | 发布时间: 1999-08-21用过NetAnts的朋友都知道,它会在IE的右键快捷菜单中加入Download All By NetAnts的项目,点一下它,NetAnts就会得到当前网页的所有连接,方便用户快速下载文件。这是怎么做的呢?
要解决这个问题,我们先抽象出问题的实质:
1)在IE地快捷菜单中加入自己的项目
2)使该项目指向自己的程序,并将所有的连接、连接描述等信息作为参数传递给自己的程序。
问题已经很明了了,对于第一步来说,很简单,修改过注册表的朋友都能轻易实现。
首先打开注册表编辑器(regedit.exe),在HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt 键下,你可以看到 Download &All By NetAnts 的子键(如果安装了NetAnts的话),其中“&”符号后面的字母标识了快捷键的按键,我想着学过Windows编程的朋友都知道。在该子键下仅有两个键值,如图,其中“默认”表示菜单所指向的文件,“Contests”则表示你添加的菜单项目在什么情况下出现。我们注意到,NetAnts指向的是NaGetAll.htm文件,根据MSDN上说,这个文件应该是个脚本文件,必要时,它会被隐藏的对话框调用,当脚本执行完毕,对话框也自动关闭。Contexts的值表示什么时候显示关联菜单,它可以取以下值:
| 0x1 | CONTEXT_MENU_DEFAULT | 缺省的菜单 |
| 0x2 | CONTEXT_MENU_IMAGE | 图象关联菜单 |
| 0x4 | CONTEXT_MENU_CONTROL | 控件关联菜单 |
| 0x8 | CONTEXT_MENU_TABLE | 表格关联菜单 |
| 0x10 | CONTEXT_MENU_TEXTSELECT | 文本选取关联菜单 |
| 0x20 | CONTEXT_MENU_ANCHOR | 锚点关联菜单 |
| 0x40 | CONTEXT_MENU_UNKNOWN | 未知元素的关联菜单 |
以上值可以通过有效的OR运算组合,如0x12,表示只在图象、文本选取关联菜单中才显示自定义的菜单条目。如果我们联想一下的话,很容易想到这可以做一个自动填表工具。更多的内容你可以到MSDN上找吧!好了,废话少说。
既然指向的是Htm文件,那么如何启动NetAnts,又如何传递参数呢?这也很简单,我们先打开NaGetAll.htm文件:
<script language="VBScript">
On Error Resume Next
set NetAntsApi = CreateObject( "NetAnts.API" ) //创建NetAnts对象
if err<>0 then
Alert("NetAnts not properly installed on this PC!")
else
set links = external.menuArguments.document.links //得到网页所有连接的集合
ReDim params(links.length*2) //links.length为所有连接的个数
params(0)=external.menuArguments.document.Url //得到当前页面的Url
for i = 0 to links.length-1
params(i*2+1)=links(i).href //连接地地址
params(i*2+2)=links(i).innerText //连接的描述
next
NetAntsApi.AddUrlList params
end if
</script>
正如前面提到的那样是VBScript,通过menuargument获得window对象,然后通过window对象得到网页的连接集合及相应的必要信息,最后调用了NetAnts对象,将所有的信息以数组的形式传递给NetAnts对象,我们所要做的就是创建自己的COM对象。
创建COM对象不太容易,但用VB,Delphi这样的快速开发工具到也不难。下面笔者就用C++ Builder实际来创建一个COM对象来完成上述功能。
启动C++ Builder创建一个新的工程,在Form1中加入一个ListBox组件,用于显示加入的连接地址。在该工程下新建一个Automation Object,如图,
输入GetUrl,其余保持不便,按OK钮,这样C++ Builder将为你创建一系列文件用于描述COM结构,我们所要做的就是添加接口和方法。
在IGetUrl接口中加入AddHrefList方法,并且添加一个Variant*类型的参数pList,设置返回值为HRESULT,如图:
然后点按刷新按钮 ,C++ Builder会自动刷新所需文件。在工程管理器中打开GetUrlImpl.cpp文件,会看到刚才接口的实现函数的声明,添加如下代码,并保存工程。
Variant* vp=(Variant*)pList; //转换为Variant类,在此转换成SafeArray*也可,但麻烦一些
int di=vp->ArrayDimCount(); //得到数组的维数
if (di>1)
return E_FAIL;
int hb=vp->ArrayHighBound(); //得到数组的上下标
int lb=vp->ArrayLowBound();
for (int n=lb;n<=hb;n++)
{
Variant vi=vp->GetElement(n); //得到数组的元素
String ai=String(vi);
Form1->ListBox1->Items->Add(ai);
}
return S_OK;
现在,一个自动化对象对象已经创建完成。编译运行程序。就在系统中自动注册了类,以及类的所有接口。接下来就很简单了,按照NaGetAll.htm文件的形式写一个VBScript,如下:
<script language="VBScript">
On Error Resume Next
set OB = CreateObject( "Project1.GetUrl" )
if err<>0 then
Alert("必要的类没有注册!")
else
set links = external.menuArguments.document.links
ReDim params(links.length)
params(0)=external.menuArguments.document.Url
for i = 0 to links.length-1
params(i+1)=links(i).href
next
OB.AddHrefList params
Alert("你成功了!")
end if
</script>
并且在注册表中加入开始讲的那样的键值,好了所有的工作都做完了。不过细心的读者会发现上述代码与NaGetAll.htm还是有一点出入,主要就在最后的Alert("我成功了!")上,这是为了解决对象生存期的问题,为了解决这个问题,需要在上面代码的开始加入:
AddRef(),这是IUnKnown接口的方法,用于增加对象的应用计数,防止对象在非必要是自动被卸载,当然如果你确定可以卸载对象了,则在必要的地方加入Release(),这同样是IUnKnown接口的方法,用于减少对象应用计数,当引用计数为 0时,Windows会自动卸载对象。
- 相关文章:
发表评论
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。






