白乔原创:Shell基础类CShell
实现方法
本类封装了一些常用的Shell操作,包括:创建快捷方式,获取特殊目录路径(如:我的电脑)、枚举制定目录(如:桌面)的子项列表等。
头文件:
// Shell.h: interface for the CShell class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_SHELL_H__6D15D05C_CD8B_4422_BFAF_D0A70F36E352__INCLUDED_) #define AFX_SHELL_H__6D15D05C_CD8B_4422_BFAF_D0A70F36E352__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 class CShell //Shell文件基础类 { public: BOOL FreeMemory(void * pBuffer); BOOL CreateLink(LPCITEMIDLIST lpi, CString sPathLink, CString sDescription = "", BOOL bByName = false); LPITEMIDLIST GetChildByName(LPITEMIDLIST pParent, CString sChildName); LPITEMIDLIST GetItemByPath(int nRootFolder, CString sRelativePath); BOOL GetSpecialFolderPath(int nFolder, CString & sPath); BOOL BrowseForFolder(CString & sFolderPath, CString sTitle); BOOL CreateLink(CString sPathSource, CString sPathLink, CString sDescription = ""); //方法 BOOL IsValidPath(CString Path); void GetFileInfo(LPITEMIDLIST lpi, UINT uFlags,SHFILEINFO * psfi); int GetItemIcon(LPITEMIDLIST lpi, UINT uFlags); BOOL GetItemName(LPSHELLFOLDER lpsf, LPITEMIDLIST lpi, DWORD dwFlags, LPTSTR lpFriendlyName); UINT GetSize(LPCITEMIDLIST pidl); LPITEMIDLIST CopyPidl(LPMALLOC lpMalloc, LPITEMIDLIST lpi); LPITEMIDLIST CreatePidl(UINT cbSize); LPITEMIDLIST ConcatPidl(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2); HIMAGELIST GetImageList(BOOL bSmall); }; #endif // !defined(AFX_SHELL_H__6D15D05C_CD8B_4422_BFAF_D0A70F36E352__INCLUDED_)
类实现:
// Shell.cpp: implementation of the CShell class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "Shell.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// HIMAGELIST CShell::GetImageList(BOOL bSmall) { SHFILEINFO shFinfo; HIMAGELIST hLargeImageList=(HIMAGELIST)SHGetFileInfo("C:\\", 0, &shFinfo, sizeof(shFinfo), SHGFI_SYSICONINDEX | bSmall ? SHGFI_SMALLICON : SHGFI_LARGEICON); return hLargeImageList; } LPITEMIDLIST CShell::ConcatPidl(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2) { LPITEMIDLIST pidlNew; UINT cb1; UINT cb2; if (pidl1) cb1 = GetSize(pidl1) - sizeof(pidl1->mkid.cb); else cb1 = 0; cb2 = GetSize(pidl2); pidlNew = CreatePidl(cb1 + cb2); if (pidlNew) { if (pidl1) memcpy(pidlNew, pidl1, cb1); memcpy(((LPTSTR)pidlNew) + cb1, pidl2, cb2); } return pidlNew; } LPITEMIDLIST CShell::CreatePidl(UINT cbSize) { LPMALLOC lpMalloc; HRESULT hr; LPITEMIDLIST pidl=NULL; hr=SHGetMalloc(&lpMalloc); if (FAILED(hr)) return 0; pidl=(LPITEMIDLIST)lpMalloc->Alloc(cbSize); if (pidl) memset(pidl, 0, cbSize); // zero-init for external task alloc if (lpMalloc) lpMalloc->Release(); return pidl; } LPITEMIDLIST CShell::CopyPidl(LPMALLOC lpMalloc, LPITEMIDLIST lpi) { LPITEMIDLIST lpiTemp; lpiTemp=(LPITEMIDLIST)lpMalloc->Alloc(lpi->mkid.cb+sizeof(lpi->mkid.cb)); CopyMemory((PVOID)lpiTemp, (CONST VOID *)lpi, lpi->mkid.cb+sizeof(lpi->mkid.cb)); return lpiTemp; } UINT CShell::GetSize(LPCITEMIDLIST pidl) { UINT cbTotal = 0; if (pidl) { cbTotal += sizeof(pidl->mkid.cb); while (pidl->mkid.cb) { cbTotal += pidl->mkid.cb; LPTSTR lpMem=(LPTSTR)pidl; lpMem += pidl->mkid.cb; pidl = (LPITEMIDLIST)lpMem; } } return cbTotal; } BOOL CShell::GetItemName(LPSHELLFOLDER lpsf, LPITEMIDLIST lpi, DWORD dwFlags, LPTSTR lpFriendlyName) { BOOL bSuccess=TRUE; STRRET str; if (NOERROR==lpsf->GetDisplayNameOf(lpi, dwFlags, &str)) { switch (str.uType) { case STRRET_WSTR: WideCharToMultiByte(CP_ACP, 0, str.pOleStr, -1, lpFriendlyName, _MAX_PATH, NULL, NULL); break; case STRRET_OFFSET: lstrcpy(lpFriendlyName, (LPTSTR)lpi+str.uOffset); break; case STRRET_CSTR: lstrcpy(lpFriendlyName, (LPTSTR)str.cStr); break; default: bSuccess = FALSE; break; } } else bSuccess = FALSE; return bSuccess; } int CShell::GetItemIcon(LPITEMIDLIST lpi, UINT uFlags) { SHFILEINFO sfi; GetFileInfo(lpi,uFlags,&sfi); return sfi.iIcon; } void CShell::GetFileInfo(LPITEMIDLIST lpi, UINT uFlags, SHFILEINFO *psfi) { SHGetFileInfo((LPCSTR)lpi, 0, psfi, sizeof(SHFILEINFO), uFlags); } BOOL CShell::IsValidPath(CString Path) { Path += "*.*"; CFileFind Finder; return Finder.FindFile(Path); } BOOL CShell::CreateLink(CString sPathSource, CString sPathLink, CString sDescription) { return CreateLink((LPCITEMIDLIST)(LPSTR)(LPCTSTR)sPathSource, sPathLink, sDescription, TRUE); } //显示选择文件夹窗口 //参数 sFolderPath:用于返回用户选择的文件夹的路径 //参数 sTitle:用于指定选择文件夹窗口的标题 //返回值 :操作结果,用户取消选择或操作失败返回FALSE,否则TRUE BOOL CShell::BrowseForFolder(CString & sFolderPath, CString sTitle) { BROWSEINFO bi; char Buffer[_MAX_PATH]; bi.hwndOwner = NULL; bi.pidlRoot = NULL; bi.pszDisplayName = Buffer; bi.lpszTitle = sTitle; bi.ulFlags = 0; bi.lpfn = NULL; LPITEMIDLIST pIDList = SHBrowseForFolder(& bi); if (!pIDList) return FALSE; SHGetPathFromIDList(pIDList, Buffer); sFolderPath = Buffer; LPMALLOC lpMalloc; if (FAILED(SHGetMalloc(& lpMalloc))) return FALSE; //释放内存 lpMalloc->Free(pIDList); lpMalloc->Release(); return TRUE; } BOOL CShell::GetSpecialFolderPath(int nFolder, CString &sPath) { char cPath[_MAX_PATH]; if(! SUCCEEDED( :: SHGetSpecialFolderPath( NULL, cPath, nFolder, TRUE))) return FALSE; sPath = cPath; return TRUE; } LPITEMIDLIST CShell::GetItemByPath(int nRootFolder, CString sRelativePath) { LPITEMIDLIST ppidl = NULL; SHGetFolderLocation(NULL, nRootFolder, NULL, 0, &ppidl); //解析sRelativePath int nStart = 0; while(ppidl) { int nEnd = sRelativePath.Find("\\", nStart); CString sChildName; if(nEnd < 0) { sChildName = sRelativePath.Mid(nStart); } else { sChildName = sRelativePath.Mid(nStart, nEnd - nStart); } if(!sChildName.IsEmpty()) { LPITEMIDLIST oppidl = ppidl; ppidl = GetChildByName(ppidl, sChildName); FreeMemory(oppidl); } if(nEnd < 0) break; nStart = nEnd + 1; } return ppidl; } LPITEMIDLIST CShell::GetChildByName(LPITEMIDLIST pParent, CString sChildName) { LPMALLOC pMalloc = NULL; IShellFolder *psfParent = NULL; IShellFolder *psfThis = NULL; LPCITEMIDLIST pidlRelative = NULL; LPITEMIDLIST ppidl = NULL; LPITEMIDLIST pChild = NULL; SHGetMalloc(&pMalloc); //获取pParent的父级IShellFolder if(SUCCEEDED(SHBindToParent(pParent, IID_IShellFolder, (void **) &psfParent, &pidlRelative))) { //获取pParent的IShellFolder if(SUCCEEDED(psfParent->BindToObject(pidlRelative, 0, IID_IShellFolder, (void **)&psfThis))) { DWORD dwFlags = SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN; LPENUMIDLIST lpe = NULL; if(SUCCEEDED(psfThis->EnumObjects(NULL, dwFlags, &lpe))) { ULONG nFetched; int i = 0; //枚举父目录下的文件 while (S_OK == lpe->Next(1, &pChild, &nFetched)) { char sItemName[_MAX_PATH]; if(!GetItemName(psfThis, pChild, SHGDN_NORMAL, sItemName)) break; if(sChildName == sItemName) { ppidl = ConcatPidl(pParent, pChild); break; } } } psfThis->Release(); } psfParent->Release(); } return ppidl; } BOOL CShell::CreateLink(LPCITEMIDLIST lpi, CString sPathLink, CString sDescription, BOOL bByName) { HRESULT hres; IShellLink * psl; //Get a pointer to the IShellLink interface. hres = CoCreateInstance( CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void * *) & psl); if (SUCCEEDED(hres)) { IPersistFile * ppf; // Set the path to the shortcut target and add the // description. if(bByName) psl->SetPath((LPSTR)lpi); else psl->SetIDList(lpi); psl->SetDescription(sDescription); // Query IShellLink for the IPersistFile interface for saving the // shortcut in persistent storage. hres = psl->QueryInterface(IID_IPersistFile, (void * *) & ppf); if (SUCCEEDED(hres)) { // Save the link by calling IPersistFile::Save. WORD wsz[MAX_PATH]; MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sPathLink, -1, wsz,MAX_PATH); hres = ppf->Save(wsz, TRUE); ppf->Release(); } psl->Release(); } return SUCCEEDED(hres); } BOOL CShell::FreeMemory(void *pBuffer) { LPMALLOC lpMalloc; if (FAILED(SHGetMalloc(&lpMalloc))) return FALSE; //释放内存 lpMalloc->Free(pBuffer); lpMalloc->Release(); return TRUE; }
注:转载文章需注明来源:VCer.net 文章地址:http://vcer.net/1076417661380.html
如果你觉得VCer.net不错,而且你愿意为VCer.net捐赠一元钱,那么点击后面的捐赠按钮吧:)
我得意,我用他的代码;
我自豪,他用我的代码!
void main() { printf("hello, vcer!"); }
A B C D E