我酷下载
您的位置:首页-> 技术文章-> -> Visual C++-> VC6.0实现快捷方式中的查找功能(1)

阅读排行




VC6.0实现快捷方式中的查找功能(1)

作者未知 来源未知 加入时间:2006-1-23 人气:132
最近写一个开发辅助工具,在这个过程要做一个类似文件快捷方式中查找目标的功能,先查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函数 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中文版.


相关文章
  • VC6.0实现快捷方式中的查找功能(2)
  • 相关软件

    联系我们 广告服务 友情链接 版权说明 软件发布 下载帮助

    CopyRight
    2005-2016 www.5qcn.net All Rights Reserved 版权所有 【我酷】下载