

码龄10年
暂无认证
34147访问
1
等级
8获赞
3
评论
热门文章
-
一.某岛之人物对象及其加密函数解析
2148
-
一.《传奇M》装备栏遍历的突破口
1791
-
二.某龙端游中LUA的分析和调用
1539
-
一.《轩辕传奇》周围遍历之二叉树
1386
-
一.《UE4奥丁》人物最大属性
1331
最新评论
-
20240228阿⑤
积分乍获得
-
20231124ziher
666
-
20230909八月老师
什麼時候發佈易語言支持庫呢
五.API打开指定文件所在的目录并选中该文件
Heart
2023-10-04 18:44:11 发布
359
分类专栏: Win32开发 文章标签: API打开指定文件 选中该文件
一.说明
通常情况下,我们用ShellExecute就可以实现“打开指定文件所在的目录并选中该文件”的功能,代码如下所示:
CString str = _T("/select, E:\\TestDir\\test.txt"); ShellExecute( NULL, _T("open"), _T("explorer.exe"), str, NULL, SW_SHOWNORMAL );
二.问题阐述
如上所示,使用“/select,“参数(注意:“/select”参数后面的逗号不能丢)。但用ShellExecute实现的功能是有问题的:当所在的文件夹已经打开,且选中的是其他的文件,如果此时执行ShellExecute,会将文件夹窗口置顶显示,但是不能选中目标文件。于是,查看QQ的做法,QQ是每一次都打开一个新的窗口,这样可以通过“/n, /select,“参数可以实现。但这样的处理不是最合理的,最合理的做法:如果文件夹已经打开,就不用再重新打开一次,直接置顶显示,并选中目标文件。
三.解决方案
通过查阅相关资料,得知可以通过调用系统库shell32.dll中的非公开API函数SHOpenFolderAndSelectItems来实现上述功能,代码如下所示:
bool OpenFolderAndSelectFile( CString strFilePath ) { LPSHELLFOLDER pDesktopFolder; ::CoInitialize( NULL ); if ( FAILED( SHGetDesktopFolder( &pDesktopFolder ) ) ) { ::CoUninitialize(); return false; } LPITEMIDLIST pidl; ULONG chEaten; WCHAR wfilePath[MAX_PATH+1] = { 0 }; //IShellFolder::ParseDisplayName要传入宽字节 #ifdef _UNICODE _tcscpy( wfilePath, strFilePath ); #else MultiByteToWideChar( CP_ACP, 0, (LPCSTR)strFilePath, -1, wfilePath, MAX_PATH ); #endif LPWSTR lpWStr = wfilePath; HRESULT hr = pDesktopFolder->ParseDisplayName( NULL, 0, lpWStr, &chEaten, &pidl, NULL ); if ( FAILED( hr ) ) { pDesktopFolder->Release(); ::CoUninitialize(); return false; } LPCITEMIDLIST cpidl = pidl; bool bSucceedOrNot = false; //SHOpenFolderAndSelectItems是非公开的API函数,需要从shell32.dll获取 //该函数只有XP及以上的系统才支持,Win2000和98是不支持的, //如果后面要支持上述老的系统,则要添加额外的处理代码 HMODULE hShell32DLL = ::LoadLibrary( _T("shell32.dll") ); ASSERT( hShell32DLL != NULL ); if( hShell32DLL ) { typedef HRESULT (WINAPI *pSelFun)( LPCITEMIDLIST pidlFolder, UINT cidl, LPCITEMIDLIST *apidl, DWORD dwFlags ); pSelFun pFun = (pSelFun)::GetProcAddress( hShell32DLL, "SHOpenFolderAndSelectItems" ); ::FreeLibrary( hShell32DLL ); ASSERT( pFun != NULL ); if( pFun != NULL ) { // 第二个参数cidl置为0,表示是选中文件 bSucceedOrNot = SUCCEEDED(pFun(cpidl, 0, NULL, 0)); } } pDesktopFolder->Release();// 释放pDesktopFolder ::CoUninitialize(); return bSucceedOrNot; }


评论列表