WEB开发网
开发学院软件开发VC 如何实现快捷方式中的查找目标功能 阅读

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

 2007-03-15 21:53:14 来源:WEB开发网   
核心提示: pIdlFile = pidl;/// 找出目标文件中文件名的偏移量while (cb = pIdlFile->mkid.cb){pidl2 = pIdlFile;pIdlFile = (ITEMIDLIST*)((BYTE*)pIdlFile + cb);}cb = pidl2-&
   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函数 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;
  HRESULT (WINAPI *gpfSHOpenFolderAndSelectItems)(LPCITEMIDLIST *pidlFolder, UINT cidl, LPCITEMIDLIST *apidl, DWORD dwFlags);
  HINSTANCE ghShell32;
/// 只有WinXp及以上及系统才支持SHOpenFolderAndSelectItems() API
/// 那其它系统该怎么实现这个功能呢?只能采用其它的方法来处理
/// 首先用XP跟踪到SHOpenFolderAndSelectItems()API中,看它是如何处理的,再用同样的方法去实现
/// 其它系统的这个功能使用工具 VC6 .net 2003 MSDN Ollydbg v1.10中文版
  ghShell32 = LoadLibrary(_T("Shell32.DLL"));
  if (ghShell32 == NULL)
    return FALSE;
  gpfSHOpenFolderAndSelectItems =
         (HRESULT (WINAPI*)(LPCITEMIDLIST*, UINT, LPCITEMIDLIST*, DWORD)) GetProcAddress(ghShell32, "SHOpenFolderAndSelectItems");
  if (gpfSHOpenFolderAndSelectItems != NULL)
  {
    /// 可以获得SHOpenFolderAndSelectItems()函数的API地址
    if (SUCCEEDED(gpfSHOpenFolderAndSelectItems((LPCITEMIDLIST*)pidlFolder,0,(LPCITEMIDLIST*)NULL,0)))
    {
      ///直接调用系统的功能
      FreeLibrary(ghShell32);
      return TRUE;
    }
    FreeLibrary(ghShell32);
    return FALSE;
  }
  FreeLibrary(ghShell32);
  /// 当操作系统不支持SHOpenFolderAndSelectItems()函数的API时的处理,
  /// 自已动手写一个与系统功能相同的代码
  pidl = pidlFolder;
  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;
  }
  return FALSE;
}
void FindTarget(CString str)
{
  HRESULT hres;
  IShellLink *psl;
  ITEMIDLIST *pidl;
  IPersistFile *ppf;
CoInitialize(NULL);
  // Get a pointer to the IShellLink interface.
  hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
        IID_IShellLink, (LPVOID*)&psl);
  if (SUCCEEDED(hres))
  {
    // 设置目标文件
    psl->SetPath(str);
    /// 获得目标文件的ITEMIDLIST
    psl->GetIDList(&pidl);
    // Get a pointer to the IPersistFile interface.
    hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf);
    if (SUCCEEDED(hres))
    {
      WCHAR wsz[MAX_PATH];
#ifdef _UNICODE
      wcscpy(wsz, str);
#else
      // Ensure that the string is Unicode.
      MultiByteToWideChar(CP_ACP, 0, str, -1, wsz, MAX_PATH);
#endif
      // Load the shortcut.
      hres = ppf->Load(wsz, STGM_READ);
      if (SUCCEEDED(hres))
      {
        /// 获得快捷方式的ITEMIDLIST
        psl->GetIDList(&pidl);
      }m
      ppf->Release();
    }
    /// 打开文件夹并选中项目
    XZSHOpenFolderAndSelectItems(pidl);
    psl->Release();
  }
  CoUninitialize();
}
在VC6下编译后的代码,通过98,2k,XP的测试。

上一页  1 2 

Tags:如何 实现 快捷

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接