当前位置: 首页 > 图文教程 > 开发语言 > VC++ > 如何实现快捷方式中的查找目标功能

VC++
几个数字信号处理算法程序
简易软盘镜像工具的实现及操作系统编写初步
教你使用正则表达式
C++ 扩展和嵌入 Python
拷贝构造和赋值操作符,C#和本机 C++ 代码的互用性
精通VC与Matlab联合编程(六)
精通VC与Matlab联合编程(五)
一个排序用的C++函数模板
浅析VC与MATLAB联合编程
C++编译器如何实现异常处理
文件重定义冲突的分析与解决
一步一步实现MFC扩展DLL中导出类和对话框
C宏:智者的利刃,愚者的恶梦!
引用的作用
《UTF-8与GB2312之间的互换》的改进
程序风格的要素-C++风格指南
VC+6.0实现文本串的自由拆分
怎样给串行化类分配版本号(可配置版本模式)
在常规的编程任务中使用新的 <tuple> 库
使用 typedef 抑制劣质代码

VC++ 中的 如何实现快捷方式中的查找目标功能


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 113 ::
收藏到网摘: n/a

如何实现快捷方式中的查找目标功能

作者:梁永喜

下载源代码

  最近写一个开发辅助工具,在这个过程要做一个类似文件快捷方式中查找目标的功能,先查MSDN98,大家不要见笑,我现在一直都用它,没有相应的API,后又. Net 2003中的MSDN,找到了可以实现该功能的API,SHOpenFolderAndSelectItems()函数,它的原型如下:
(具体用法参考MSDN)“Opens a Microsoft® Windows® Explorer window with specified items in a particular folder selected.”

HRESULT SHOpenFolderAndSelectItems(    LPCITEMIDLIST pidlFolder,    UINT cidl,    LPCITEMIDLIST *apidl,    DWORD dwFlags);

  但是,它需要Windows XP及上,若在Win2000或Win98如何实现它呢?于是我就上网搜索,几经周折最终搜到的一篇文章,但它只是利用工具通过反汇编Windows API函数得到的代码,可能可以实现与快捷方式相同的对话框(我没有试过),但其代码可读性非常差,我只能参考一下大概的流程,他提到一个非常重要的一点,那就是使用一个未公开的API函数SHGetIDispatchForFolder,它可帮助我打开文件夹。好不多说了,下面是关键的部分:
  查找目标功能,分为两个步骤,首先打开或找到目标文件所在的文件夹,其次在打开的文件夹中选中相应的项目(即文件)。在说这个步骤之前,先认识一下,下面两个结构

typedef struct _SHITEMID { USHORT cb; BYTE abID[1]; } SHITEMID, * LPSHITEMID; typedef const SHITEMID * LPCSHITEMID; typedef struct _ITEMIDLIST { SHITEMID mkid;} ITEMIDLIST, * LPITEMIDLIST; typedef const ITEMIDLIST * LPCITEMIDLIST; 
  这两个结构的数据保存的是项目定义符列表(仅是字面翻译),这个结构所表示的文件夹及文件除了正常的,还包括一些特殊的文件夹及文件(如目录,我的电脑等),SHGetIDispatchForFolder函数正是用它的做为参数,可以打开一些特殊的文件夹。SHGetIDispatchForFolder函数的原型是 :
 HRESULT (WINAPI*gpfSHGetIDispatchForFolder)(ITEMIDLIST* pidl, IWebBrowserApp** ppIWebBrowserApp); 
  通常快捷方式给我的ITEMIDLIST是包含文件名的,若直接调用上面的函数,它将直接会打开出目标文件,而不是打开文件夹。下面是区分文件及文件夹的代码:
	pIdlFile = pidl;	/// 找出目标文件中文件名的偏移量	while (cb = pIdlFile->mkid.cb) 	{	pidl2 = pIdlFile;	pIdlFile = (ITEMIDLIST*)((BYTE*)pIdlFile + cb);	}	cb = pidl2->mkid.cb;	pidl2->mkid.cb = 0;
下面是打开文件夹及选中文件的代码,相信大家不难理解。
	/// 打开目标文件所在的文件夹	if (SUCCEEDED(GetShellFolderViewDual(pidl, &pIShellFolderViewDual))) 	{	pidl2->mkid.cb = cb;	// 0 Deselect the item. 	// 1 Select the item. 	// 3 Put the item in edit mode. 	// 4 Deselect all but the specified item. 	// 8 Ensure the item is displayed in the view. 	// 0x10 Give the item the focus. 	COleVariant bszFile(pidl2);	if(pIShellFolderViewDual != NULL)	{	/// 选中相应的选项	pIShellFolderViewDual->SelectItem(bszFile, 0x1d);	pIShellFolderViewDual->Release();	}	return TRUE;	}
  源代码中包含了一个DEMO。下面是完整的函数,可以直接调用FindTarget(CString str)参数为文件名,若是快捷方式则会自动指向其目标。若代码中已做过COM的初始化工作,请删除CoInitialize(NULL);及CoUninitialize();语句。
HRESULT GetShellFolderViewDual(ITEMIDLIST* pidl, IShellFolderViewDual** ppIShellFolderViewDual){	IWebBrowserApp* pIWebBrowserApp;	IDispatch* pDoc;	HWND hWnd;	HRESULT hr;	HINSTANCE ghSHDOCVW;	HRESULT (WINAPI*gpfSHGetIDispatchForFolder)(ITEMIDLIST* pidl, IWebBrowserApp** ppIWebBrowserApp);	*ppIShellFolderViewDual = NULL;	ghSHDOCVW = LoadLibrary(_T("SHDOCVW.DLL"));	if (ghSHDOCVW == NULL)	return FALSE;	pIWebBrowserApp=NULL;	gpfSHGetIDispatchForFolder =	(HRESULT (WINAPI*)(ITEMIDLIST*, IWebBrowserApp**)) GetProcAddress(ghSHDOCVW, "SHGetIDispatchForFolder");	if (gpfSHGetIDispatchForFolder == NULL)	return FALSE;	/// 调用未公开的API函数 SHGetIDispatchFor