用VC6.0实现快捷方式中的查找目标功能

文章作者 100test 发表时间 2007:08:06 12:56:56
来源 100Test.Com百考试题网


最近写一个开发辅助工具,在这个过程要做一个类似文件快捷方式中查找目标的功能,先查MSDN98,大家不要见笑,我现在一直都用它,没有相应的API,后又. Net 2003中的MSDN,找到了可以实现该功能的API,SHOpenFolderAndSelectItems()函数,它的原型如下:

  (具体用法参考MSDN)“Opens a Microsoft®. Windows®. Explorer window with specified items in a particular folder 0selected.”

  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 De0select the item.
   // 1 Select the item.
   // 3 Put the item in edit mode.
   // 4 De0select 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函数 SHGetIDispatchForFolder
   if (SUCCEEDED(gpfSHGetIDispatchForFolder(pidl, &.pIWebBrowserApp)))
   {
   if (SUCCEEDED(pIWebBrowserApp->get_HWND((long*)&.hWnd)))
   {
   SetForegroundWindow(hWnd).
   ShowWindow(hWnd, SW_SHOWNORMAL).
   }

   if (SUCCEEDED(hr = pIWebBrowserApp->get_Document(&.pDoc)))
   {
   pDoc->QueryInterface(IID_IShellFolderViewDual, (void**) ppIShellFolderViewDual).
   pDoc->Release().
   }

   pIWebBrowserApp->Release().
   }
   FreeLibrary(ghSHDOCVW).

   return TRUE.
  }

  BOOL XZSHOpenFolderAndSelectItems(ITEMIDLIST *pidlFolder)
  {
   ITEMIDLIST *pidl, *pidl2.
   ITEMIDLIST* pIdlFile.
   USHORT cb.
   IShellFolderViewDual* pIShellFolderViewDual.
src="/ncre2/js/wxgg.js">

相关文章


用Winsock实现语音全双工通信
在程序中重启自己的一种方法
用VC6.0实现快捷方式中的查找目标功能
程序开发:目前主流开发技术的分析和总结
澳大利亚华人论坛
考好网
日本华人论坛
华人移民留学论坛
英国华人论坛