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

VC++
在类VC的界面实现中加入目录树
软件换肤技术在 BCB 中的实现
利用非模窗口生成MDI介面
报表输出轻松搞定
Windows 中不规则窗体的编程实现
解说Win32的窗口子类化
使用测试优先方法开发用户界面
一个简单的登录对话框的实现
一个简单的日记本程序
从资源中加载皮肤
一个在RichEdit中添加表情图象的类
ActiveSkin 4.3 软件换肤在VC中的实现
一种另类“关于(About)”对话框的动态显示方法
对话框打印预览及打印
关于如何换肤、子类化的解决方案
制作 MSN、QQ 的消息提示窗口
如何对 BCGControlBarPro 进行换肤
定制个性化的对话框窗口类
改变窗口中的光标形状
更新MFC中的视图,跟踪.NET Framework中的事件

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


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 121 ::
收藏到网摘: 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