added some development tools
[windows-sources.git] / developer / VC / WTL80 / Samples / WTLExplorer / ShellMgr.Cpp
blob764475cd30ac9f89c39e37b8d0b943fb84cc5027
1 // shellmgr.cpp
3 #include "stdafx.h"
4 #include <atlctrls.h>
5 #include <atlctrlx.h>
7 #include "shellmgr.h"
8 #include "mainfrm.h"
11 int CShellMgr::GetIconIndex(LPITEMIDLIST lpi, UINT uFlags)
13         SHFILEINFO sfi = { 0 };
14         DWORD_PTR dwRet = ::SHGetFileInfo((LPCTSTR)lpi, 0, &sfi, sizeof(SHFILEINFO), uFlags);
15         return (dwRet != 0) ? sfi.iIcon : -1;
18 void CShellMgr::GetNormalAndSelectedIcons(LPITEMIDLIST lpifq, LPTVITEM lptvitem)
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);
26 LPITEMIDLIST CShellMgr::ConcatPidls(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
28         UINT cb1 = 0;
29         if (pidl1 != NULL)   // May be NULL
30                 cb1 = GetSize(pidl1) - sizeof(pidl1->mkid.cb);
32         UINT cb2 = GetSize(pidl2);
34         LPITEMIDLIST pidlNew = (LPITEMIDLIST)::CoTaskMemAlloc(cb1 + cb2);
35         if (pidlNew != NULL)
36         {
37                 if (pidl1 != NULL)
38                         memcpy(pidlNew, pidl1, cb1);
40                 memcpy(((LPSTR)pidlNew) + cb1, pidl2, cb2);
41         }
43         return pidlNew;
46 BOOL CShellMgr::GetName(LPSHELLFOLDER lpsf, LPITEMIDLIST lpi, DWORD dwFlags, LPTSTR lpFriendlyName)
48         BOOL bSuccess = TRUE;
49         STRRET str = { STRRET_CSTR };
51         if (lpsf->GetDisplayNameOf(lpi, dwFlags, &str) == NOERROR)
52         {
53                 USES_CONVERSION;
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         }
77         return bSuccess;
80 LPITEMIDLIST CShellMgr::Next(LPCITEMIDLIST pidl)
82         LPSTR lpMem = (LPSTR)pidl;
83         lpMem += pidl->mkid.cb;
84         return (LPITEMIDLIST)lpMem;
87 UINT CShellMgr::GetSize(LPCITEMIDLIST pidl)
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         }
100         return cbTotal;
103 LPITEMIDLIST CShellMgr::CopyITEMID(LPITEMIDLIST lpi)
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;
110 LPITEMIDLIST CShellMgr::GetFullyQualPidl(LPSHELLFOLDER lpsf, LPITEMIDLIST lpi)
112         TCHAR szBuff[MAX_PATH] = { 0 };
114         if (!GetName(lpsf, lpi, SHGDN_FORPARSING, szBuff))
115                 return NULL;
117         CComPtr<IShellFolder> spDeskTop;
118         HRESULT hr = ::SHGetDesktopFolder(&spDeskTop);
119         if (FAILED(hr))
120                 return NULL;
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);
128         if (FAILED(hr))
129                 return NULL;
131         return lpifq;
134 BOOL CShellMgr::DoContextMenu(HWND hWnd, LPSHELLFOLDER lpsfParent, LPITEMIDLIST lpi, POINT point)
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;
141         HMENU hMenu = ::CreatePopupMenu();
142         if(hMenu == NULL)
143                 return FALSE;
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;
150         int idCmd = ::TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_RETURNCMD | TPM_RIGHTBUTTON, point.x, point.y, 0, hWnd, NULL);
152         if (idCmd != 0)
153         {
154                 USES_CONVERSION;
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         }
170         ::DestroyMenu(hMenu);
172         return TRUE;