没有找到合适的产品?
联系客服协助选型:023-68661681
提供3000多款全球软件/控件产品
针对软件研发的各个阶段提供专业培训与技术咨询
根据客户需求提供定制化的软件开发服务
全球知名设计软件,显著提升设计质量
打造以经营为中心,实现生产过程透明化管理
帮助企业合理产能分配,提高资源利用率
快速打造数字化生产线,实现全流程追溯
生产过程精准追溯,满足企业合规要求
以六西格玛为理论基础,实现产品质量全数字化管理
通过大屏电子看板,实现车间透明化管理
对设备进行全生命周期管理,提高设备综合利用率
实现设备数据的实时采集与监控
利用数字化技术提升油气勘探的效率和成功率
钻井计划优化、实时监控和风险评估
提供业务洞察与决策支持实现数据驱动决策
翻译|其它|编辑:郝浩|2006-01-11 09:36:00.000|阅读 1094 次
概述:
# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>
下载源代码
最近写一个开发辅助工具,在这个过程要做一个类似文件快捷方式中查找目标的功能,先查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中文版
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的测试。
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com
面对“数字中国”建设和中国制造2025战略实施的机遇期,中车信息公司紧跟时代的步伐,以“集约化、专业化、标准化、精益化、一体化、平台化”为工作目标,大力推进信息服务、工业软件等核心产品及业务的发展。在慧都3D解决方案的实施下,清软英泰建成了多模型来源的综合轻量化显示平台、实现文件不失真的百倍压缩比、针对模型中的大模型文件,在展示平台上进行流畅展示,提升工作效率,优化了使用体验。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
服务电话
重庆/ 023-68661681
华东/ 13452821722
华南/ 18100878085
华北/ 17347785263
客户支持
技术支持咨询服务
服务热线:400-700-1020
邮箱:sales@evget.com
关注我们
地址 : 重庆市九龙坡区火炬大道69号6幢
慧都科技 版权所有 Copyright 2003-
2025 渝ICP备12000582号-13 渝公网安备
50010702500608号