3、DoAddToFavDlg函数
“DoAddToFavDlg”函数也是“shdocvw.dll”暴露出来的函数之一,其原型如下:
typedef BOOL (CALLBACK* LPFNADDFAV)(HWND, TCHAR*, UINT, TCHAR*, UINT,LPITEMIDLIST);
第一个参数正是我们想要的父窗口句柄,第二和第四个参数分别是初始目录(一般来说就是收藏夹目录)和要添加的链接的名字(比如网页的Title),第三和第五个参数分别是第二和第四两个缓冲区的长度,而最后一个参数则是指向与第二个参数目录相关的item identifier list的指针(PIDL)。但最奇怪的是这里并没有像“AddFavorite”函数一样的链接URL,那链接是怎样添加的呢?答案是“手动创建”。
第二个参数在函数调用返回后会包含用户在“添加到收藏夹”对话框中选择或创建的完整链接路径名(如“X:\XXX\mylink.url”),我们就根据这个路径和网页的URL来创建链接,代码如下(为简化,此处省去检查"shdocvw.dll"是否已在内存中的代码,参见《Internet Explorer 编程简述(三)“整理收藏夹”对话框》):
void CMyHtmlView::OnFavAddtofav()
{
typedef BOOL (CALLBACK* LPFNADDFAV)(HWND, TCHAR*, UINT, TCHAR*, UINT,LPITEMIDLIST);
HMODULE hMod = (HMODULE)LoadLibrary("shdocvw.dll");
if (hMod)
{
LPFNADDFAV lpfnDoAddToFavDlg = (LPFNADDFAV)GetProcAddress( hMod, "DoAddToFavDlg");
if (lpfnDoAddToFavDlg)
{
TCHAR szPath[MAX_PATH];
LPITEMIDLIST pidlFavorites;
if (SHGetSpecialFolderPath(NULL, szPath, CSIDL_FAVORITES, TRUE) &&
(SUCCEEDED(SHGetSpecialFolderLocation(NULL, CSIDL_FAVORITES, &pidlFavorites))))
{
TCHAR szTitle[MAX_PATH];
strcpy(szTitle, GetLocationName());
TCHAR szURL[MAX_PATH];
strcpy(szURL, GetLocationURL());
BOOL bOK = lpfnDoAddToFavDlg(m_hWnd, szPath,
sizeof(szPath)/sizeof(szPath[0]), szTitle,
sizeof(szTitle)/sizeof(szTitle[0]), pidlFavorites);
CoTaskMemFree(pidlFavorites);
if (bOK)
CreateInternetShortcut( szURL, szPath, ""); //创建Internet快捷方式
}
}
FreeLibrary(hMod);
}
return;
}
实现CreateInternetShortcut函数创建Internet快捷方式,可以用读写INI文件的方法,但更好的则是利用IUniformResourceLocator接口。
HRESULT CMyHtmlView::CreateInternetShortcut(LPCSTR pszURL, LPCSTR pszURLfilename,
LPCSTR szDescription,LPCTSTR szIconFile,int nIndex)
{
HRESULT hres;
CoInitialize(NULL);
IUniformResourceLocator *pHook;
hres = CoCreateInstance (CLSID_InternetShortcut, NULL, CLSCTX_INPROC_SERVER,
IID_IUniformResourceLocator, (void **)&pHook);
if (SUCCEEDED (hres))
{
IPersistFile *ppf;
IShellLink *psl;
// Query IShellLink for the IPersistFile interface for
hres = pHook->QueryInterface (IID_IPersistFile, (void **)&ppf);
hres = pHook->QueryInterface (IID_IShellLink, (void **)&psl);
if (SUCCEEDED (hres))
{
WORD wsz [MAX_PATH]; // buffer for Unicode string
// Set the path to the shortcut target.
pHook->SetURL(pszURL,0);
hres = psl->SetIconLocation(szIconFile,nIndex);
if (SUCCEEDED (hres))
{
// Set the description of the shortcut.
hres = psl->SetDescription (szDescription);
if (SUCCEEDED (hres))
{
// Ensure that the string consists of ANSI characters.
MultiByteToWideChar (CP_ACP, 0, pszURLfilename, -1, wsz, MAX_PATH);
// Save the shortcut via the IPersistFile::Save member function.
hres = ppf->Save (wsz, TRUE);
}
}
// Release the pointer to IPersistFile.
ppf->Release ();
psl->Release ();
}
// Release the pointer to IShellLink.
pHook->Release ();
}
return hres;
}
好,上面的方法虽然麻烦一点,但总算解决了“模态窗口”的问题,使得我们的程序不至于让用户鄙视。但是问题又来了,我们发现“允许脱机使用”是Disabled的,那“自定义”也就无从谈起了,尽管90%的人都没有使用过IE提供的脱机浏览。
难道我们的希望要破灭吗?我们一方面想像调用“AddFavorite”函数一样的不必手动创建链接,一方面又要模态显示窗口,就像IE那样,还能自定义脱机浏览。
3、脚本方式
许多网页上都会有一个按钮或链接“添加本页到收藏夹”,实际上通过下面的脚本显示模态的“添加到收藏夹”对话框将网页加入到收藏夹。
window.external.AddFavorite(location.href, document.title);
这里的external对象是WebBrowser内置的COM自动化对象,以实现对文档对象模型(DOM)的扩展(我们也可以通过IDocHostUIHandler实现自己的扩展).查阅MSDN可以得知external对象的的方法与IShellUIHelper接口提供的方法是一样的。我们有理由相信,IShellUIHelper提供了对WebBrowser内置的external对象的访问,如果在适当的地方创建IShellUIHelper接口的实例,也许调用“AddFavorite”函数显示出来的就是模态对话框了。问题是我们还没有找到这样的地方。
从上面的脚本,我们很自然地又想到另一个方法。如果能够让网页来执行上面的脚本,岂不是问题就解决了?说做就做,如下:
void CMyHtmlView::OnFavAddtofav()
{
CString strUrl = GetLocationURL();
CString strTitle = GetLocationName();
CString strjs = "javascri
[1] [2] 下一页
[聊天工具]用Windows98第二版直接共享Internet [系统软件]Internet Explorer 编程简述(繁体版)
[系统软件]单击链接后无法打开新的 Internet Explorer 窗口或… [系统软件]delphi2005帮助系统使用了microsoft document exp…
[系统软件]对Internet Explorer Web 控件做一点修改 [系统软件]OLE with the internet explorer
[系统软件]打造个性化的Internet Explorer [系统软件]3dMax导出.x文件以及3D Explorer
[常用软件]微软Internet Explorer 8最新动向 [常用软件]PDF全能管家——PDFExplorer