1 //////////////////////////////////////
\r
5 #include "ShellWrapper.h"
\r
8 /////////////////////////////////////////////////////////////
\r
9 // Global function in the ShellWrapper namespace
\r
12 namespace ShellWrapper
\r
14 ///////////////////////////////////
\r
15 //global functionnct definitions (within this namespace)
\r
16 BOOL GetFullFileName(LPCITEMIDLIST pidlFull, LPTSTR pszPathName)
\r
18 if (!::SHGetPathFromIDList(pidlFull, pszPathName))
\r
20 pszPathName[0] = _T('\0');
\r
27 BOOL GetDisplayName(LPCITEMIDLIST pidlFull, LPTSTR pszDisplayName)
\r
31 // Get the display name of the item
\r
32 if(!::SHGetFileInfo((LPCTSTR)pidlFull, 0, &sfi, sizeof(sfi), SHGFI_PIDL | SHGFI_DISPLAYNAME))
\r
34 pszDisplayName[0] = _T('\0');
\r
38 ::lstrcpyn(pszDisplayName, sfi.szDisplayName, MAX_PATH -1);
\r
43 ///////////////////////////////////
\r
44 //CContextMenu function definitions
\r
45 CContextMenu::CContextMenu() : m_pIContextMenu(NULL)
\r
49 CContextMenu::~CContextMenu()
\r
51 if (m_pIContextMenu)
\r
52 m_pIContextMenu->Release();
\r
55 void CContextMenu::Attach(IContextMenu* pIContextMenu)
\r
57 if (m_pIContextMenu)
\r
58 m_pIContextMenu->Release();
\r
59 m_pIContextMenu = pIContextMenu;
\r
62 HRESULT CContextMenu::InvokeCommand(CMINVOKECOMMANDINFO& Ici)
\r
64 HRESULT hr = m_pIContextMenu->InvokeCommand(&Ici);
\r
68 TRACE(_T("CContextMenu::InvokeCommand failed\n"));
\r
73 HRESULT CContextMenu::QueryInterface(REFIID iid, CContextMenu2& ccm2)
\r
76 if (IID_IContextMenu2 == iid)
\r
78 IContextMenu2* pIContextMenu2 = NULL;
\r
79 hr = m_pIContextMenu->QueryInterface(iid, (VOID**)&pIContextMenu2);
\r
81 ccm2.Attach(pIContextMenu2);
\r
84 TRACE(_T("CContextMenu::QueryInterface failed\n"));
\r
88 TRACE(_T("Not Implemented!\n"));
\r
93 HRESULT CContextMenu::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
\r
95 HRESULT hr = m_pIContextMenu->QueryContextMenu(hmenu, indexMenu, idCmdFirst, idCmdLast, uFlags) ;
\r
98 TRACE(_T("CContextMenu::QueryContextMenu failed\n"));
\r
104 ////////////////////////////////////
\r
105 //CContextMenu2 function definitions
\r
106 CContextMenu2::CContextMenu2() : m_pIContextMenu2(NULL)
\r
110 CContextMenu2::~CContextMenu2()
\r
112 if (m_pIContextMenu2)
\r
113 m_pIContextMenu2->Release();
\r
116 void CContextMenu2::Attach(IContextMenu2* pIContextMenu2)
\r
118 if (m_pIContextMenu2)
\r
119 m_pIContextMenu2->Release();
\r
120 m_pIContextMenu2 = pIContextMenu2;
\r
123 HRESULT CContextMenu2::HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam)
\r
125 HRESULT hr = m_pIContextMenu2->HandleMenuMsg(uMsg, wParam, lParam);
\r
127 if((hr != S_OK) && (hr !=E_NOTIMPL))
\r
129 TRACE(_T("CContextMenu2::HandleMenuMsg failed\n"));
\r
135 void CContextMenu2::Release()
\r
137 m_pIContextMenu2->Release();
\r
138 m_pIContextMenu2 = 0;
\r
142 ///////////////////////////////////
\r
143 //CShellFolder function definitions
\r
144 CShellFolder::CShellFolder() : m_IShellFolder(NULL)
\r
148 CShellFolder::CShellFolder(const CShellFolder& csfSource) : m_IShellFolder(NULL)
\r
153 void CShellFolder::operator=(const CShellFolder& csfSource)
\r
158 CShellFolder::~CShellFolder()
\r
163 void CShellFolder::Attach(LPSHELLFOLDER IShellFolder)
\r
164 //Converts SHELLFOLDER pointer to a CShellFolder object.
\r
165 //The memory allocated for the SHELLFOLDER pointer is released
\r
166 // in the destructor
\r
169 m_IShellFolder = IShellFolder;
\r
172 HRESULT CShellFolder::BindToObject(const Cpidl& cpidl, LPBC pbc, REFIID riid, CShellFolder& NewFolder)
\r
174 LPSHELLFOLDER FolderTemp;
\r
175 LPITEMIDLIST pidl = cpidl.GetPidl();
\r
177 HRESULT hr = m_IShellFolder->BindToObject(pidl, pbc, riid, (VOID**)&FolderTemp);
\r
179 NewFolder.Attach(FolderTemp);
\r
182 TRACE(_T("CShellFolder::BindToObject failed\n"));
\r
188 HRESULT CShellFolder::CompareIDs(LPARAM lParam, const Cpidl& cpidl1, const Cpidl& cpidl2)
\r
190 LPITEMIDLIST pidl1 = cpidl1.GetPidl();
\r
191 LPITEMIDLIST pidl2 = cpidl2.GetPidl();
\r
192 return m_IShellFolder->CompareIDs(lParam, pidl1, pidl2);
\r
195 void CShellFolder::Copy(LPSHELLFOLDER Source)
\r
196 //Assigns the value to the CShellFolder object.
\r
198 Delete(); //Release the current m_IShellFolder
\r
199 m_IShellFolder = Source;
\r
204 void CShellFolder::Copy(const CShellFolder& Source)
\r
205 //Assigns the value to the CShellFolder object.
\r
207 Delete(); //Release the current m_IShellFolder
\r
208 m_IShellFolder = Source.m_IShellFolder;
\r
209 if (Source.m_IShellFolder)
\r
213 HRESULT CShellFolder::CreateViewObject(HWND hwnd, REFIID riid, CContextMenu& ccm)
\r
216 HRESULT hr = m_IShellFolder->CreateViewObject(hwnd, riid, (LPVOID*)&pcm);
\r
221 TRACE(_T("CShellFolder::CreateViewObject failed\n"));
\r
226 HRESULT CShellFolder::EnumObjects(HWND hwndOwner, int grfFlags, CEnumIDList& cenumIDList)
\r
228 LPENUMIDLIST pEnum;
\r
230 if (m_IShellFolder)
\r
232 hr = m_IShellFolder->EnumObjects(hwndOwner, grfFlags, &pEnum);
\r
234 cenumIDList.Attach(pEnum);
\r
236 TRACE(_T("CShellFolder::EnumObjects failed\n"));
\r
239 TRACE(_T("CShellFolder::EnumObjects failed\n"));
\r
244 HRESULT CShellFolder::GetAttributesOf(UINT cidl, const Cpidl& cpidl, ULONG& rgfInOut)
\r
246 LPCITEMIDLIST pidl = cpidl.GetPidl();
\r
247 HRESULT hr = m_IShellFolder->GetAttributesOf(cidl, &pidl, &rgfInOut);
\r
251 TRACE(_T("CShellFolder::GetAttributesOf failed\n"));
\r
256 HRESULT CShellFolder::SHGetDesktopFolder()
\r
258 HRESULT hr = ::SHGetDesktopFolder(&m_IShellFolder);
\r
262 TRACE(_T("CShellFolder::SHGetDesktopFolder failed\n"));
\r
267 HRESULT CShellFolder::GetUIObjectOf(HWND hwndOwner, UINT nItems, Cpidl* cpidlArray, REFIID riid, UINT rgfReserved, CContextMenu& cm)
\r
268 //cpidlArray is either an array of Cpidl or a pointer to a single Cpidl
\r
270 LPCITEMIDLIST* pPidlArray;
\r
271 pPidlArray = (LPCITEMIDLIST*)::CoTaskMemAlloc(sizeof(LPITEMIDLIST) * nItems);
\r
272 if(!pPidlArray) return 0;
\r
274 for(UINT i = 0; i < nItems; i++)
\r
275 pPidlArray[i] = cpidlArray[i].GetPidl();
\r
278 HRESULT hr = m_IShellFolder->GetUIObjectOf(hwndOwner, nItems, pPidlArray, riid, &rgfReserved, (VOID**)&ppv);
\r
284 TRACE(_T("CShellFolder::GetUIObjectOf failed\n"));
\r
287 CoTaskMemFree(pPidlArray);
\r
291 //Deletes the memory allocated for m_IShellFolder (if any)
\r
292 void CShellFolder::Delete()
\r
294 if (m_IShellFolder)
\r
295 m_IShellFolder->Release();
\r
296 m_IShellFolder = NULL;
\r
300 //////////////////////////////////
\r
301 //CEnumIDList function definitions
\r
302 CEnumIDList::CEnumIDList() : m_pEnumIDList(NULL)
\r
306 CEnumIDList::~CEnumIDList()
\r
309 m_pEnumIDList->Release();
\r
312 //Converts a LPENUMIDLIST to a CEnumIDList object.
\r
313 // The destructor will release memory allocated for the LPENUMIDLIST
\r
314 void CEnumIDList::Attach(LPENUMIDLIST EnumList)
\r
316 m_pEnumIDList = EnumList;
\r
319 HRESULT CEnumIDList::Next(ULONG Elements, Cpidl& cpidl, ULONG& ulFetched)
\r
324 HRESULT hr = m_pEnumIDList->Next(Elements, &pidl, &ulFetched);
\r
326 cpidl.Attach(pidl);
\r
328 if ((NOERROR != hr) && (S_FALSE != hr))
\r
330 TRACE(_T("CEnumIDList::Next failed\n"));
\r
338 //Cpidl function definitions
\r
339 Cpidl::Cpidl() : m_pidl(NULL), m_pidlParent(NULL)
\r
341 ::SHGetMalloc(&m_pMalloc);
\r
344 Cpidl::Cpidl(const Cpidl& cpidlSource) : m_pidl(NULL), m_pidlParent(NULL)
\r
346 ::SHGetMalloc(&m_pMalloc);
\r
350 void Cpidl::operator= (const Cpidl& cpidlSource)
\r
355 BOOL Cpidl::operator== (const Cpidl& cpidl)
\r
357 return IsEqual(cpidl);
\r
360 const Cpidl operator+ (const Cpidl& cpidlFull, const Cpidl& cpidlRel)
\r
362 //Appends cpidlRel to cpidlFull.
\r
363 //The order of the cpidls DOES matter.
\r
364 //The fully qualified cpidl must come first.
\r
366 Temp.Concatenate(cpidlFull, cpidlRel);
\r
374 m_pMalloc->Free(m_pidlParent);
\r
376 m_pMalloc->Release();
\r
379 void Cpidl::Attach(LPCITEMIDLIST pidl)
\r
380 //Converts a ITEMIDLIST pointer to a Cpidl object
\r
381 //The memory allocated for the original pidl will be released
\r
382 // in the destructor
\r
384 Delete(); //Release the memory for m_pidl
\r
385 m_pidl = (LPITEMIDLIST)pidl;
\r
388 void Cpidl::Delete()
\r
391 m_pMalloc->Free(m_pidl);
\r
395 HRESULT Cpidl::SHGetSpecialFolderLocation(HWND hwnd, int csidl)
\r
397 Delete(); //Release the memory for m_pidl
\r
398 HRESULT hr = ::SHGetSpecialFolderLocation(hwnd, csidl, &m_pidl);
\r
401 TRACE(_T("Cpidl::SHGetSpecialFolderLocation failed\n"));
\r
406 DWORD_PTR Cpidl::SHGetFileInfo(DWORD dwFileAttributes, SHFILEINFO& sfi, UINT uFlags)
\r
408 LPITEMIDLIST pidl = m_pidl;
\r
409 return (DWORD_PTR)::SHGetFileInfo((LPCTSTR)pidl, dwFileAttributes, &sfi, sizeof(SHFILEINFO), uFlags);
\r
412 void Cpidl::Copy(const Cpidl& cpidlSource)
\r
413 //The Cpidl object stores a copy of the pidlSource's m_pidl.
\r
415 Copy(cpidlSource.GetPidl());
\r
418 void Cpidl::Copy(LPCITEMIDLIST pidlSource)
\r
419 //The Cpidl object stores a copy of the pidlSource. The memory allocated to
\r
420 // pidlSource is NOT released.
\r
423 Delete(); //Release the memory for m_pidl
\r
425 if(NULL == pidlSource) return;
\r
427 //Allocate memory for m_pidl
\r
428 cbSource = GetSize(pidlSource);
\r
429 m_pidl = (LPITEMIDLIST)m_pMalloc->Alloc(cbSource);
\r
430 if (!m_pidl) return;
\r
432 ::CopyMemory(m_pidl, pidlSource, cbSource);
\r
435 LPITEMIDLIST Cpidl::GetParent()
\r
437 // Delete m_pidlParent
\r
438 UINT nSize = GetSize(m_pidl);
\r
440 m_pMalloc->Free(m_pidlParent);
\r
441 m_pidlParent = NULL;
\r
443 // Make sure it's a valid PIDL.
\r
444 if (NULL == m_pidl)
\r
447 // Copy m_pidl to m_pidlParent
\r
448 m_pidlParent = (LPITEMIDLIST)m_pMalloc->Alloc(nSize);
\r
452 ::CopyMemory(m_pidlParent, m_pidl, nSize);
\r
454 // Identify the last item's position
\r
455 if (m_pidlParent->mkid.cb)
\r
457 LPITEMIDLIST pidlNext = m_pidlParent;
\r
458 LPITEMIDLIST pidlTemp = m_pidlParent;
\r
460 while (pidlNext->mkid.cb)
\r
462 pidlTemp = pidlNext;
\r
463 pidlNext = GetNextItem(pidlTemp);
\r
465 // Remove the last item, set it's size to 0.
\r
466 pidlTemp->mkid.cb = 0;
\r
468 return m_pidlParent;
\r
471 LPITEMIDLIST Cpidl::GetRelative()
\r
472 //Stores a copy of the relative pidl obtained from a fully qualified pidl source.
\r
474 if(NULL == m_pidl) return NULL;
\r
476 LPITEMIDLIST pidlNext = m_pidl;
\r
477 LPITEMIDLIST pidlRel = m_pidl;
\r
479 while( pidlNext->mkid.cb )
\r
481 pidlNext = GetNextItem(pidlNext);
\r
482 if (pidlNext->mkid.cb)
\r
483 pidlRel = (LPITEMIDLIST)pidlNext;
\r
486 UINT nPos = GetSize(m_pidl) - GetSize(pidlRel);
\r
487 return (LPITEMIDLIST)((LPBYTE)m_pidl + nPos);
\r
490 void Cpidl::Concatenate(const Cpidl& cpidlParent, const Cpidl& cpidlRel)
\r
491 //Creates a new Cpidl object by concatenating (chain together)
\r
492 // a parent and relative Cpidl.
\r
494 Concatenate(cpidlParent.GetPidl(), cpidlRel.GetPidl());
\r
497 void Cpidl::Concatenate(LPCITEMIDLIST pidlParent, LPCITEMIDLIST pidlRel)
\r
498 //Create a new fully qualified Cpidl object from a Parent pidl
\r
499 // and a relative pidl.
\r
504 Delete(); //Release the current m_pidl
\r
506 if (!pidlRel) return; //pidlRel should not be NULL
\r
508 // Calculate the size of pidlParent without the two bytes of NULL terminator.
\r
509 // This size can be zero if pidlParent points to the desktop.
\r
511 cb1 = GetSize(pidlParent) - (2 * sizeof(BYTE));
\r
513 cb2 = GetSize(pidlRel);
\r
515 // Create a new ITEMIDLIST that is the size of both pidlParent and pidlRel,
\r
516 // then copy pidlParent and pidlRel to the new list.
\r
517 m_pidl = (LPITEMIDLIST)m_pMalloc->Alloc(cb1 + cb2);
\r
520 ::ZeroMemory(m_pidl, cb1 + cb2);
\r
522 ::CopyMemory(m_pidl, pidlParent, cb1);
\r
524 ::CopyMemory(((LPBYTE)m_pidl) + cb1, pidlRel, cb2);
\r
528 UINT Cpidl::GetSize(LPCITEMIDLIST pidl)
\r
531 if (!pidl) return 0;
\r
535 cbTotal += pidl->mkid.cb;
\r
536 pidl = GetNextItem(pidl);
\r
539 // Requires a 16 bit zero value for the NULL terminator
\r
540 cbTotal += 2 * sizeof(BYTE);
\r
545 LPITEMIDLIST Cpidl::GetNextItem(LPCITEMIDLIST pidl)
\r
547 // Check for valid pidl.
\r
551 // Get the size of the specified item identifier.
\r
552 int cb = pidl->mkid.cb;
\r
554 // If the size is zero, it is the end of the list.
\r
558 // Add cb to pidl (casting to increment by bytes).
\r
559 return (LPITEMIDLIST) (((LPBYTE) pidl) + cb);
\r
562 BOOL Cpidl::IsEqual(const Cpidl &cpidl)
\r
565 sf.SHGetDesktopFolder();
\r
566 return (0 == sf.CompareIDs(0, *this, cpidl) );
\r