/3rd_party/wtl/Samples/WTLExplorer/ShellMgr.Cpp
C++ | 173 lines | 138 code | 32 blank | 3 comment | 23 complexity | c0180279cef9dd30f268932b05acee52 MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause, JSON, MPL-2.0-no-copyleft-exception, GPL-2.0, GPL-3.0, LGPL-3.0, BSD-2-Clause
1// shellmgr.cpp 2 3#include "stdafx.h" 4#include <atlctrls.h> 5#include <atlctrlx.h> 6 7#include "shellmgr.h" 8#include "mainfrm.h" 9 10 11int CShellMgr::GetIconIndex(LPITEMIDLIST lpi, UINT uFlags) 12{ 13 SHFILEINFO sfi = { 0 }; 14 DWORD_PTR dwRet = ::SHGetFileInfo((LPCTSTR)lpi, 0, &sfi, sizeof(SHFILEINFO), uFlags); 15 return (dwRet != 0) ? sfi.iIcon : -1; 16} 17 18void CShellMgr::GetNormalAndSelectedIcons(LPITEMIDLIST lpifq, LPTVITEM lptvitem) 19{ 20 int nRet = lptvitem->iImage = GetIconIndex(lpifq, SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON); 21 ATLASSERT(nRet >= 0); 22 nRet = lptvitem->iSelectedImage = GetIconIndex(lpifq, SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_OPENICON); 23 ATLASSERT(nRet >= 0); 24} 25 26LPITEMIDLIST CShellMgr::ConcatPidls(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2) 27{ 28 UINT cb1 = 0; 29 if (pidl1 != NULL) // May be NULL 30 cb1 = GetSize(pidl1) - sizeof(pidl1->mkid.cb); 31 32 UINT cb2 = GetSize(pidl2); 33 34 LPITEMIDLIST pidlNew = (LPITEMIDLIST)::CoTaskMemAlloc(cb1 + cb2); 35 if (pidlNew != NULL) 36 { 37 if (pidl1 != NULL) 38 memcpy(pidlNew, pidl1, cb1); 39 40 memcpy(((LPSTR)pidlNew) + cb1, pidl2, cb2); 41 } 42 43 return pidlNew; 44} 45 46BOOL CShellMgr::GetName(LPSHELLFOLDER lpsf, LPITEMIDLIST lpi, DWORD dwFlags, LPTSTR lpFriendlyName) 47{ 48 BOOL bSuccess = TRUE; 49 STRRET str = { STRRET_CSTR }; 50 51 if (lpsf->GetDisplayNameOf(lpi, dwFlags, &str) == NOERROR) 52 { 53 USES_CONVERSION; 54 55 switch (str.uType) 56 { 57 case STRRET_WSTR: 58 lstrcpy(lpFriendlyName, W2CT(str.pOleStr)); 59 ::CoTaskMemFree(str.pOleStr); 60 break; 61 case STRRET_OFFSET: 62 lstrcpy(lpFriendlyName, (LPTSTR)lpi + str.uOffset); 63 break; 64 case STRRET_CSTR: 65 lstrcpy(lpFriendlyName, A2CT(str.cStr)); 66 break; 67 default: 68 bSuccess = FALSE; 69 break; 70 } 71 } 72 else 73 { 74 bSuccess = FALSE; 75 } 76 77 return bSuccess; 78} 79 80LPITEMIDLIST CShellMgr::Next(LPCITEMIDLIST pidl) 81{ 82 LPSTR lpMem = (LPSTR)pidl; 83 lpMem += pidl->mkid.cb; 84 return (LPITEMIDLIST)lpMem; 85} 86 87UINT CShellMgr::GetSize(LPCITEMIDLIST pidl) 88{ 89 UINT cbTotal = 0; 90 if (pidl != NULL) 91 { 92 cbTotal += sizeof(pidl->mkid.cb); // Null terminator 93 while (pidl->mkid.cb != NULL) 94 { 95 cbTotal += pidl->mkid.cb; 96 pidl = Next(pidl); 97 } 98 } 99 100 return cbTotal; 101} 102 103LPITEMIDLIST CShellMgr::CopyITEMID(LPITEMIDLIST lpi) 104{ 105 LPITEMIDLIST lpiTemp = (LPITEMIDLIST)::CoTaskMemAlloc(lpi->mkid.cb + sizeof(lpi->mkid.cb)); 106 ::CopyMemory((PVOID)lpiTemp, (CONST VOID*)lpi, lpi->mkid.cb + sizeof(lpi->mkid.cb)); 107 return lpiTemp; 108} 109 110LPITEMIDLIST CShellMgr::GetFullyQualPidl(LPSHELLFOLDER lpsf, LPITEMIDLIST lpi) 111{ 112 TCHAR szBuff[MAX_PATH] = { 0 }; 113 114 if (!GetName(lpsf, lpi, SHGDN_FORPARSING, szBuff)) 115 return NULL; 116 117 CComPtr<IShellFolder> spDeskTop; 118 HRESULT hr = ::SHGetDesktopFolder(&spDeskTop); 119 if (FAILED(hr)) 120 return NULL; 121 122 ULONG ulEaten = 0; 123 LPITEMIDLIST lpifq = NULL; 124 ULONG ulAttribs = 0; 125 USES_CONVERSION; 126 hr = spDeskTop->ParseDisplayName(NULL, NULL, T2W(szBuff), &ulEaten, &lpifq, &ulAttribs); 127 128 if (FAILED(hr)) 129 return NULL; 130 131 return lpifq; 132} 133 134BOOL CShellMgr::DoContextMenu(HWND hWnd, LPSHELLFOLDER lpsfParent, LPITEMIDLIST lpi, POINT point) 135{ 136 CComPtr<IContextMenu> spContextMenu; 137 HRESULT hr = lpsfParent->GetUIObjectOf(hWnd, 1, (const struct _ITEMIDLIST**)&lpi, IID_IContextMenu, 0, (LPVOID*)&spContextMenu); 138 if(FAILED(hr)) 139 return FALSE; 140 141 HMENU hMenu = ::CreatePopupMenu(); 142 if(hMenu == NULL) 143 return FALSE; 144 145 // Get the context menu for the item. 146 hr = spContextMenu->QueryContextMenu(hMenu, 0, 1, 0x7FFF, CMF_EXPLORE); 147 if(FAILED(hr)) 148 return FALSE; 149 150 int idCmd = ::TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_RETURNCMD | TPM_RIGHTBUTTON, point.x, point.y, 0, hWnd, NULL); 151 152 if (idCmd != 0) 153 { 154 USES_CONVERSION; 155 156 // Execute the command that was selected. 157 CMINVOKECOMMANDINFO cmi = { 0 }; 158 cmi.cbSize = sizeof(CMINVOKECOMMANDINFO); 159 cmi.fMask = 0; 160 cmi.hwnd = hWnd; 161 cmi.lpVerb = T2CA(MAKEINTRESOURCE(idCmd - 1)); 162 cmi.lpParameters = NULL; 163 cmi.lpDirectory = NULL; 164 cmi.nShow = SW_SHOWNORMAL; 165 cmi.dwHotKey = 0; 166 cmi.hIcon = NULL; 167 hr = spContextMenu->InvokeCommand(&cmi); 168 } 169 170 ::DestroyMenu(hMenu); 171 172 return TRUE; 173}