网际快车(Flasgget)和影音传送带(Nettransport)是目前国内非常有名的下载工具,也许我们的软件中需要调用它们进行下载,最简单的方式是直接用URL作为参数调用它们的主进程,因为这种软件通常都能够识别这种简单的命令行。但是如果要一次添加多个URL呢?这样做就不行了。由于这两个软件(通常这类软件都会)在Microsoft网页浏览器控件的右键菜单里添加下载单个URL与下载网页内所有URL两个右键菜单项,即浏览器可以启动它们下载单个URL和多个URL。那我们就来研究一下它们是怎么被浏览器启动的吧。
以网际快车为例,它是通过两个VBScript脚本来被启动的,下载单个URL的的脚本文件为jc_link.htm,下载网页中的所有URL的脚本文件为jc_all.htm。jc_link.htm的内容如下:
我们可以不管其中提取鼠标所点击的链接的URL,我们只关心它是怎么被启动和添加URL的。显然它是通过CreateObject("JetCar.Netscape")来创建COM对象,然后通过AddUrl(Url, Info, external.menuArguments.document.Url)添加URL。AddUrl是接口提供的方法。参数从其命名来看也知道它们分别是要下载的链接的URL,链接的显示文本及链接所在网页的URL。同样,我们看看jc_all.htm的内容:
它所使用的方法是AddUrlList,从它的参数的生成来看,这是个比较复杂的参数,后面我会着重讲述怎么在VC里构造这个参数。
下面我们就来看看在VC里面怎么启动Flashget并添加URL。上面的VBScript是通过CreateObject创建COM对象的,我们应该怎么做呢?有两种方法:一是我们可以使用CreateInstance函数来创建,二是使用VC的ClassWizard生成接口类。我们懒人来使用第二种方法。方法是在ClassWizard中“Add Class From a typelib”,然后选择Flashget安装目录里的Jccatch.dll,接口类IJetCarNetscape就被自动生成了。于是添加单个URL的代码可以如下写(代码来自本人的软件拙作“网址抓取器”):
IJetCarNetscape flashget;
if(!flashget.CreateDispatch(_T("JetCar.Netscape")))
{
return FALSE;
}
flashget.AddUrl(strURL, _T("由网址抓取器添加"), strRefer);
下面我们来看看怎么样向Flashget添加多个URL。前面说过,AddUrlList的参数似乎看起来有点复杂。它是一个字符串数组,第一个元素为链接所在网页的URL,接下来依次为链接的URL及其显示文本。下面的代码演示了如何向COM接口传递数组:
IJetCarNetscape flashget;
if(!flashget.CreateDispatch(_T("JetCar.Netscape")))
{
AfxMessageBox(_T("没有找到Flashget的下载接口!你可能需要重装Flashget。"));
return ;
}
CReportCtrl& rc = GetReportCtrl();
int nItemCount = rc.GetItemCount();
if(nItemCount <= 0)
{
return;
}
CString strUrl, strRemark;
int nArraySize = nItemCount * 2 + 1;
SAFEARRAY *psa = CreateSafeArray(nArraySize);
VARIANT varList;
varList.vt = VT_BSTR;
long ix[] = {0};
varList.bstrVal = SysAllocString(L"http://hendysoft.51.net/"); // 第一项为网页链接
SafeArrayPutElement(psa, ix, &varList);
ix[0] ++;
for (; ix[0] < nArraySize; ix[0] ++)
{
strUrl = rc.GetItemText(ix[0]/2, 2);
strRemark = strUrl.Mid(strUrl.ReverseFind('/') + 1);
varList.bstrVal = SysAllocString(T2OLE(strUrl));
SafeArrayPutElement(psa, ix, &varList);
ix[0] ++;
varList.bstrVal = SysAllocString(T2OLE(strRemark));
SafeArrayPutElement(psa, ix, &varList);
}
varList.vt = VT_ARRAY | VT_VARIANT | VT_BYREF; // VBScript Array
varList.pparray=&psa;
flashget.AddUrlList(&varList);
SafeArrayDestroy(psa);
同样,对于影音传送带添加单个URL与添加多个URL的代码分别为:
INTIEAddUrl nettransport;
if(!nettransport.CreateDispatch(_T("NTIEHelper.NTIEAddUrl")))
{
return FALSE;
}
nettransport.AddLink(strRefer, strURL, _T("由网址抓取器添加"));
// 添加多个
URLINTIEAddUrl nettransport;
if(!nettransport.CreateDispatch(_T("NTIEHelper.NTIEAddUrl")))
{
AfxMessageBox(_T("没有找到NetTransport的下载接口!你可能需要重装NetTransport。"));
return ;
}
CReportCtrl& rc = GetReportCtrl();
int nItemCount = rc.GetItemCount();
if(nItemCount <= 0)
{
return;
}
CString strUrl, strRemark;
VARIANT *urlList = new VARIANT[nItemCount];
VARIANT *remarkList = new VARIANT[nItemCount];
for(int i = 0; i < nItemCount; i ++)
{
strUrl = rc.GetItemText(i, 2);
strRemark = strUrl.Mid(strUrl.ReverseFind('/') + 1);
VariantInit(&urlList[i]);
VariantInit(&remarkList[i]);
urlList[i].vt = VT_BSTR;
urlList[i].bstrVal = T2OLE(strUrl);
remarkList[i].vt = VT_BSTR;
remarkList[i].bstrVal = T2OLE(strRemark);
}
nettransport.AddList(_T("http://hendysoft.51.net/"), urlList, remarkList);
for(i = 0; i < nItemCount; i ++)
{
VariantClear(&urlList[i]);
VariantClear(&remarkList[i]);
}
delete []urlList;
delete []remarkList;
|