Commit before breaking everything
[matches/honours.git] / research / transmission_spectroscopy / TOF / Win32++ / samples / Explorer / src / ShellWrapper.cpp
diff --git a/research/transmission_spectroscopy/TOF/Win32++/samples/Explorer/src/ShellWrapper.cpp b/research/transmission_spectroscopy/TOF/Win32++/samples/Explorer/src/ShellWrapper.cpp
new file mode 100644 (file)
index 0000000..22d1935
--- /dev/null
@@ -0,0 +1,568 @@
+//////////////////////////////////////\r
+// ShellWrapper.cpp\r
+\r
+#include "stdafx.h"\r
+#include "ShellWrapper.h"\r
+\r
+\r
+/////////////////////////////////////////////////////////////\r
+// Global function in the ShellWrapper namespace\r
+//\r
+\r
+namespace ShellWrapper\r
+{\r
+       ///////////////////////////////////\r
+       //global functionnct definitions (within this namespace)\r
+       BOOL GetFullFileName(LPCITEMIDLIST pidlFull, LPTSTR pszPathName)\r
+       {\r
+               if (!::SHGetPathFromIDList(pidlFull, pszPathName))\r
+               {\r
+                       pszPathName[0] = _T('\0');\r
+                       return FALSE;\r
+               }\r
+\r
+               return TRUE;\r
+       }\r
+\r
+       BOOL GetDisplayName(LPCITEMIDLIST pidlFull, LPTSTR pszDisplayName)\r
+       {\r
+               SHFILEINFO     sfi;\r
+\r
+               // Get the display name of the item\r
+               if(!::SHGetFileInfo((LPCTSTR)pidlFull, 0, &sfi, sizeof(sfi), SHGFI_PIDL | SHGFI_DISPLAYNAME))\r
+               {\r
+                       pszDisplayName[0] = _T('\0');\r
+                       return FALSE;\r
+               }\r
+\r
+               ::lstrcpyn(pszDisplayName, sfi.szDisplayName, MAX_PATH -1);\r
+               return TRUE;\r
+       }\r
+\r
+\r
+       ///////////////////////////////////\r
+       //CContextMenu function definitions\r
+       CContextMenu::CContextMenu() : m_pIContextMenu(NULL)\r
+       {\r
+       }\r
+\r
+       CContextMenu::~CContextMenu()\r
+       {\r
+               if (m_pIContextMenu)\r
+                       m_pIContextMenu->Release();\r
+       }\r
+\r
+       void CContextMenu::Attach(IContextMenu* pIContextMenu)\r
+       {\r
+               if (m_pIContextMenu)\r
+                       m_pIContextMenu->Release();\r
+               m_pIContextMenu = pIContextMenu;\r
+       }\r
+\r
+       HRESULT CContextMenu::InvokeCommand(CMINVOKECOMMANDINFO& Ici)\r
+       {\r
+               HRESULT hr = m_pIContextMenu->InvokeCommand(&Ici);\r
+\r
+               if (hr != NOERROR)\r
+               {\r
+                       TRACE(_T("CContextMenu::InvokeCommand failed\n"));\r
+               }\r
+               return hr;\r
+       }\r
+\r
+       HRESULT CContextMenu::QueryInterface(REFIID iid, CContextMenu2& ccm2)\r
+       {\r
+               HRESULT hr = 0;\r
+               if (IID_IContextMenu2 == iid)\r
+               {\r
+                       IContextMenu2* pIContextMenu2 = NULL;\r
+                       hr = m_pIContextMenu->QueryInterface(iid, (VOID**)&pIContextMenu2);\r
+                       if (S_OK == hr)\r
+                               ccm2.Attach(pIContextMenu2);\r
+                       else\r
+                       {\r
+                               TRACE(_T("CContextMenu::QueryInterface failed\n"));\r
+                       }\r
+               }\r
+               else\r
+                       TRACE(_T("Not Implemented!\n"));\r
+\r
+               return hr;\r
+       }\r
+\r
+       HRESULT CContextMenu::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)\r
+       {\r
+               HRESULT hr = m_pIContextMenu->QueryContextMenu(hmenu, indexMenu, idCmdFirst, idCmdLast, uFlags) ;\r
+               if(hr & 0x80000000)\r
+               {\r
+                       TRACE(_T("CContextMenu::QueryContextMenu failed\n"));\r
+               }\r
+               return hr;\r
+       }\r
+\r
+\r
+       ////////////////////////////////////\r
+       //CContextMenu2 function definitions\r
+       CContextMenu2::CContextMenu2() : m_pIContextMenu2(NULL)\r
+       {\r
+       }\r
+\r
+       CContextMenu2::~CContextMenu2()\r
+       {\r
+               if (m_pIContextMenu2)\r
+                       m_pIContextMenu2->Release();\r
+       }\r
+\r
+       void CContextMenu2::Attach(IContextMenu2* pIContextMenu2)\r
+       {\r
+               if (m_pIContextMenu2)\r
+                       m_pIContextMenu2->Release();\r
+               m_pIContextMenu2 = pIContextMenu2;\r
+       }\r
+\r
+       HRESULT CContextMenu2::HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam)\r
+       {\r
+               HRESULT hr = m_pIContextMenu2->HandleMenuMsg(uMsg, wParam, lParam);\r
+\r
+               if((hr != S_OK) && (hr !=E_NOTIMPL))\r
+               {\r
+                       TRACE(_T("CContextMenu2::HandleMenuMsg failed\n"));\r
+               }\r
+\r
+               return hr;\r
+       }\r
+\r
+       void CContextMenu2::Release()\r
+       {\r
+               m_pIContextMenu2->Release();\r
+               m_pIContextMenu2 = 0;\r
+       }\r
+\r
+\r
+       ///////////////////////////////////\r
+       //CShellFolder function definitions\r
+       CShellFolder::CShellFolder() : m_IShellFolder(NULL)\r
+       {\r
+       }\r
+\r
+       CShellFolder::CShellFolder(const CShellFolder& csfSource) : m_IShellFolder(NULL)\r
+       {\r
+               Copy(csfSource);\r
+       }\r
+\r
+       void CShellFolder::operator=(const CShellFolder& csfSource)\r
+       {\r
+               Copy(csfSource);\r
+       }\r
+\r
+       CShellFolder::~CShellFolder()\r
+       {\r
+               Delete();\r
+       }\r
+\r
+       void CShellFolder::Attach(LPSHELLFOLDER IShellFolder)\r
+    //Converts SHELLFOLDER pointer to a CShellFolder object.\r
+       //The memory allocated for the SHELLFOLDER pointer is released\r
+       //  in the destructor\r
+       {\r
+               Delete();\r
+               m_IShellFolder = IShellFolder;\r
+       }\r
+\r
+       HRESULT CShellFolder::BindToObject(const Cpidl& cpidl, LPBC pbc, REFIID riid, CShellFolder& NewFolder)\r
+       {\r
+               LPSHELLFOLDER FolderTemp;\r
+               LPITEMIDLIST pidl = cpidl.GetPidl();\r
+\r
+               HRESULT hr = m_IShellFolder->BindToObject(pidl, pbc, riid, (VOID**)&FolderTemp);\r
+               if(S_OK == hr)\r
+                       NewFolder.Attach(FolderTemp);\r
+               else\r
+               {\r
+                       TRACE(_T("CShellFolder::BindToObject failed\n"));\r
+               }\r
+\r
+               return hr;\r
+       }\r
+\r
+       HRESULT CShellFolder::CompareIDs(LPARAM lParam, const Cpidl& cpidl1, const Cpidl& cpidl2)\r
+       {\r
+               LPITEMIDLIST pidl1 = cpidl1.GetPidl();\r
+               LPITEMIDLIST pidl2 = cpidl2.GetPidl();\r
+               return m_IShellFolder->CompareIDs(lParam, pidl1, pidl2);\r
+       }\r
+\r
+       void CShellFolder::Copy(LPSHELLFOLDER Source)\r
+       //Assigns the value to the CShellFolder object.\r
+       {\r
+               Delete(); //Release the current m_IShellFolder\r
+               m_IShellFolder = Source;\r
+               if (Source) \r
+                       AddRef();\r
+       }\r
+\r
+       void CShellFolder::Copy(const CShellFolder& Source)\r
+       //Assigns the value to the CShellFolder object.\r
+       {\r
+               Delete(); //Release the current m_IShellFolder\r
+               m_IShellFolder = Source.m_IShellFolder;\r
+               if (Source.m_IShellFolder)\r
+                       AddRef();\r
+       }\r
+\r
+       HRESULT CShellFolder::CreateViewObject(HWND hwnd, REFIID riid, CContextMenu& ccm)\r
+       {\r
+               IContextMenu* pcm;\r
+               HRESULT hr = m_IShellFolder->CreateViewObject(hwnd, riid, (LPVOID*)&pcm);\r
+               if (S_OK == hr)\r
+                       ccm.Attach(pcm);\r
+               else\r
+               {\r
+                       TRACE(_T("CShellFolder::CreateViewObject failed\n"));\r
+               }\r
+               return hr;\r
+       }\r
+\r
+       HRESULT CShellFolder::EnumObjects(HWND hwndOwner, int grfFlags, CEnumIDList& cenumIDList)\r
+       {\r
+               LPENUMIDLIST pEnum;\r
+               HRESULT hr = 0;\r
+               if (m_IShellFolder)\r
+               {\r
+                       hr = m_IShellFolder->EnumObjects(hwndOwner, grfFlags, &pEnum);\r
+                       if (S_OK == hr)\r
+                               cenumIDList.Attach(pEnum);\r
+                       else\r
+                               TRACE(_T("CShellFolder::EnumObjects failed\n"));\r
+               }\r
+               else\r
+                       TRACE(_T("CShellFolder::EnumObjects failed\n"));\r
+\r
+               return hr;\r
+       }\r
+\r
+       HRESULT CShellFolder::GetAttributesOf(UINT cidl, const Cpidl& cpidl, ULONG& rgfInOut)\r
+       {\r
+               LPCITEMIDLIST pidl = cpidl.GetPidl();\r
+               HRESULT hr = m_IShellFolder->GetAttributesOf(cidl, &pidl, &rgfInOut);\r
+\r
+               if (hr != S_OK)\r
+               {\r
+                       TRACE(_T("CShellFolder::GetAttributesOf failed\n"));\r
+               }\r
+               return hr;\r
+       }\r
+\r
+       HRESULT CShellFolder::SHGetDesktopFolder()\r
+       {\r
+               HRESULT hr = ::SHGetDesktopFolder(&m_IShellFolder);\r
+\r
+               if (hr != NOERROR)\r
+               {\r
+                       TRACE(_T("CShellFolder::SHGetDesktopFolder failed\n"));\r
+               }\r
+               return hr;\r
+       }\r
+\r
+       HRESULT CShellFolder::GetUIObjectOf(HWND hwndOwner, UINT nItems, Cpidl* cpidlArray, REFIID riid, UINT rgfReserved, CContextMenu& cm)\r
+       //cpidlArray is either an array of Cpidl or a pointer to a single Cpidl\r
+       {\r
+               LPCITEMIDLIST* pPidlArray;\r
+               pPidlArray = (LPCITEMIDLIST*)::CoTaskMemAlloc(sizeof(LPITEMIDLIST) * nItems);\r
+               if(!pPidlArray) return 0;\r
+\r
+               for(UINT i = 0; i < nItems; i++)\r
+                       pPidlArray[i] = cpidlArray[i].GetPidl();\r
+\r
+               IContextMenu* ppv;\r
+               HRESULT hr = m_IShellFolder->GetUIObjectOf(hwndOwner, nItems, pPidlArray, riid, &rgfReserved, (VOID**)&ppv);\r
+\r
+               if (S_OK == hr)\r
+                       cm.Attach(ppv);\r
+               else\r
+               {\r
+                       TRACE(_T("CShellFolder::GetUIObjectOf failed\n"));\r
+               }\r
+\r
+               CoTaskMemFree(pPidlArray);\r
+               return hr;\r
+       }\r
+\r
+       //Deletes the memory allocated for m_IShellFolder (if any)\r
+       void CShellFolder::Delete()\r
+       {\r
+               if (m_IShellFolder)\r
+                       m_IShellFolder->Release();\r
+               m_IShellFolder = NULL;\r
+       }\r
+\r
+\r
+       //////////////////////////////////\r
+       //CEnumIDList function definitions\r
+       CEnumIDList::CEnumIDList() : m_pEnumIDList(NULL)\r
+       {\r
+       }\r
+\r
+       CEnumIDList::~CEnumIDList()\r
+       {\r
+               if (m_pEnumIDList)\r
+                       m_pEnumIDList->Release();\r
+       }\r
+\r
+       //Converts a LPENUMIDLIST to a CEnumIDList object.\r
+       //  The destructor will release memory allocated for the LPENUMIDLIST\r
+       void CEnumIDList::Attach(LPENUMIDLIST EnumList)\r
+       {\r
+               m_pEnumIDList = EnumList;\r
+       }\r
+\r
+       HRESULT CEnumIDList::Next(ULONG Elements, Cpidl& cpidl, ULONG& ulFetched)\r
+       {\r
+               LPITEMIDLIST pidl;\r
+               if (m_pEnumIDList)\r
+               {\r
+                       HRESULT hr = m_pEnumIDList->Next(Elements, &pidl, &ulFetched);\r
+                       if (NOERROR == hr)\r
+                               cpidl.Attach(pidl);\r
+\r
+                       if ((NOERROR != hr) && (S_FALSE != hr))\r
+                       {\r
+                               TRACE(_T("CEnumIDList::Next failed\n"));\r
+                       }\r
+                       return hr;\r
+               }\r
+               else\r
+                       return S_FALSE;\r
+       }\r
+\r
+       //Cpidl function definitions\r
+       Cpidl::Cpidl() : m_pidl(NULL), m_pidlParent(NULL)\r
+       {\r
+               ::SHGetMalloc(&m_pMalloc);\r
+       }\r
+\r
+       Cpidl::Cpidl(const Cpidl& cpidlSource) : m_pidl(NULL), m_pidlParent(NULL)\r
+       {\r
+               ::SHGetMalloc(&m_pMalloc);\r
+               Copy(cpidlSource);\r
+       }\r
+\r
+       void Cpidl::operator= (const Cpidl& cpidlSource)\r
+       {\r
+               Copy(cpidlSource);\r
+       }\r
+\r
+       BOOL Cpidl::operator== (const Cpidl& cpidl)\r
+       {\r
+               return IsEqual(cpidl);\r
+       }\r
+\r
+       const Cpidl operator+ (const Cpidl& cpidlFull, const Cpidl& cpidlRel)\r
+       {\r
+               //Appends cpidlRel to cpidlFull.\r
+               //The order of the cpidls DOES matter.\r
+               //The fully qualified cpidl must come first.\r
+               Cpidl Temp;\r
+               Temp.Concatenate(cpidlFull, cpidlRel);\r
+               return Temp;\r
+       }\r
+\r
+       Cpidl::~Cpidl()\r
+       {\r
+               Delete();\r
+               if (m_pidlParent)\r
+                       m_pMalloc->Free(m_pidlParent);\r
+\r
+               m_pMalloc->Release();\r
+       }\r
+\r
+       void Cpidl::Attach(LPCITEMIDLIST pidl)\r
+       //Converts a ITEMIDLIST pointer to a Cpidl object\r
+       //The memory allocated for the original pidl will be released\r
+       //  in the destructor\r
+       {\r
+               Delete();  //Release the memory for m_pidl\r
+               m_pidl = (LPITEMIDLIST)pidl;\r
+       }\r
+\r
+       void Cpidl::Delete()\r
+       {\r
+               if (m_pidl)\r
+                       m_pMalloc->Free(m_pidl);\r
+               m_pidl = NULL;\r
+       }\r
+\r
+       HRESULT Cpidl::SHGetSpecialFolderLocation(HWND hwnd, int csidl)\r
+       {\r
+               Delete(); //Release the memory for m_pidl\r
+               HRESULT hr = ::SHGetSpecialFolderLocation(hwnd, csidl, &m_pidl);\r
+               if (hr != S_OK)\r
+               {\r
+                       TRACE(_T("Cpidl::SHGetSpecialFolderLocation failed\n"));\r
+               }\r
+               return hr;\r
+       }\r
+\r
+       DWORD_PTR Cpidl::SHGetFileInfo(DWORD dwFileAttributes, SHFILEINFO& sfi, UINT uFlags)\r
+       {\r
+               LPITEMIDLIST pidl = m_pidl;\r
+               return (DWORD_PTR)::SHGetFileInfo((LPCTSTR)pidl, dwFileAttributes, &sfi, sizeof(SHFILEINFO), uFlags);\r
+       }\r
+\r
+       void Cpidl::Copy(const Cpidl& cpidlSource)\r
+       //The Cpidl object stores a copy of the pidlSource's m_pidl.\r
+       {\r
+               Copy(cpidlSource.GetPidl());\r
+       }\r
+\r
+       void Cpidl::Copy(LPCITEMIDLIST pidlSource)\r
+       //The Cpidl object stores a copy of the pidlSource. The memory allocated to\r
+       //  pidlSource is NOT released.\r
+       {\r
+               UINT cbSource;\r
+               Delete(); //Release the memory for m_pidl\r
+\r
+               if(NULL == pidlSource) return;\r
+\r
+               //Allocate memory for m_pidl\r
+               cbSource = GetSize(pidlSource);\r
+               m_pidl = (LPITEMIDLIST)m_pMalloc->Alloc(cbSource);\r
+               if (!m_pidl) return;\r
+\r
+               ::CopyMemory(m_pidl, pidlSource, cbSource);\r
+       }\r
+\r
+       LPITEMIDLIST Cpidl::GetParent()\r
+       {\r
+       // Delete m_pidlParent\r
+               UINT nSize = GetSize(m_pidl);\r
+               if (m_pidlParent)\r
+                       m_pMalloc->Free(m_pidlParent);\r
+               m_pidlParent = NULL;\r
+\r
+       // Make sure it's a valid PIDL.\r
+               if (NULL == m_pidl)\r
+                       return(NULL);\r
+\r
+       // Copy m_pidl to m_pidlParent\r
+               m_pidlParent = (LPITEMIDLIST)m_pMalloc->Alloc(nSize);\r
+               if (!m_pidlParent)\r
+                       return NULL;\r
+\r
+               ::CopyMemory(m_pidlParent, m_pidl, nSize);\r
+\r
+       // Identify the last item's position\r
+               if (m_pidlParent->mkid.cb)\r
+               {\r
+                       LPITEMIDLIST pidlNext = m_pidlParent;\r
+                       LPITEMIDLIST pidlTemp = m_pidlParent;\r
+\r
+                       while (pidlNext->mkid.cb)\r
+                       {\r
+                               pidlTemp = pidlNext;\r
+                               pidlNext = GetNextItem(pidlTemp);\r
+                       }\r
+                       // Remove the last item, set it's size to 0.\r
+                       pidlTemp->mkid.cb = 0;\r
+               }\r
+               return m_pidlParent;\r
+       }\r
+\r
+       LPITEMIDLIST Cpidl::GetRelative()\r
+       //Stores a copy of the relative pidl obtained from a fully qualified pidl source.\r
+       {\r
+               if(NULL == m_pidl) return NULL;\r
+\r
+               LPITEMIDLIST pidlNext = m_pidl;\r
+               LPITEMIDLIST pidlRel  = m_pidl;\r
+\r
+               while( pidlNext->mkid.cb )\r
+               {\r
+                       pidlNext = GetNextItem(pidlNext);\r
+                       if (pidlNext->mkid.cb)\r
+                               pidlRel = (LPITEMIDLIST)pidlNext;\r
+               }\r
+\r
+               UINT nPos = GetSize(m_pidl) - GetSize(pidlRel);\r
+               return (LPITEMIDLIST)((LPBYTE)m_pidl + nPos);\r
+       }\r
+\r
+       void Cpidl::Concatenate(const Cpidl& cpidlParent, const Cpidl& cpidlRel)\r
+       //Creates a new Cpidl object by concatenating (chain together)\r
+       //  a parent and relative Cpidl.\r
+       {\r
+               Concatenate(cpidlParent.GetPidl(), cpidlRel.GetPidl());\r
+       }\r
+\r
+       void Cpidl::Concatenate(LPCITEMIDLIST pidlParent, LPCITEMIDLIST pidlRel)\r
+       //Create a new fully qualified Cpidl object from a Parent pidl\r
+       //  and a relative pidl.\r
+       {\r
+               UINT cb1 = 0;\r
+               UINT cb2;\r
+\r
+               Delete(); //Release the current m_pidl\r
+\r
+               if (!pidlRel) return; //pidlRel should not be NULL\r
+\r
+               // Calculate the size of pidlParent without the two bytes of NULL terminator.\r
+               // This size can be zero if pidlParent points to the desktop.\r
+               if(pidlParent)\r
+                       cb1 = GetSize(pidlParent) - (2 * sizeof(BYTE));\r
+\r
+               cb2 = GetSize(pidlRel);\r
+\r
+               // Create a new ITEMIDLIST that is the size of both pidlParent and pidlRel,\r
+               // then copy pidlParent and pidlRel to the new list.\r
+               m_pidl = (LPITEMIDLIST)m_pMalloc->Alloc(cb1 + cb2);\r
+               if (m_pidl)\r
+               {\r
+                       ::ZeroMemory(m_pidl, cb1 + cb2);\r
+                       if (pidlParent)\r
+                               ::CopyMemory(m_pidl, pidlParent, cb1);\r
+\r
+                       ::CopyMemory(((LPBYTE)m_pidl) + cb1, pidlRel, cb2);\r
+               }\r
+       }\r
+\r
+       UINT Cpidl::GetSize(LPCITEMIDLIST pidl)\r
+       {\r
+               UINT cbTotal = 0;\r
+               if (!pidl) return 0;\r
+\r
+               while(pidl)\r
+               {\r
+                       cbTotal += pidl->mkid.cb;\r
+                       pidl = GetNextItem(pidl);\r
+               }\r
+\r
+               // Requires a 16 bit zero value for the NULL terminator\r
+               cbTotal += 2 * sizeof(BYTE);\r
+\r
+               return cbTotal;\r
+       }\r
+\r
+       LPITEMIDLIST Cpidl::GetNextItem(LPCITEMIDLIST pidl)\r
+       {\r
+               // Check for valid pidl.\r
+               if(NULL == pidl)\r
+                       return NULL;\r
+\r
+               // Get the size of the specified item identifier.\r
+               int cb = pidl->mkid.cb;\r
+\r
+               // If the size is zero, it is the end of the list.\r
+               if (0 == cb)\r
+                       return NULL;\r
+\r
+               // Add cb to pidl (casting to increment by bytes).\r
+               return (LPITEMIDLIST) (((LPBYTE) pidl) + cb);\r
+       }\r
+\r
+       BOOL Cpidl::IsEqual(const Cpidl &cpidl)\r
+       {\r
+               CShellFolder sf;\r
+               sf.SHGetDesktopFolder();\r
+               return (0 == sf.CompareIDs(0, *this, cpidl) );\r
+       }\r
+}\r

UCC git Repository :: git.ucc.asn.au