Commit before breaking everything
[matches/honours.git] / research / transmission_spectroscopy / TOF / Win32++ / samples / Explorer / src / ShellWrapper.cpp
1 //////////////////////////////////////\r
2 // ShellWrapper.cpp\r
3 \r
4 #include "stdafx.h"\r
5 #include "ShellWrapper.h"\r
6 \r
7 \r
8 /////////////////////////////////////////////////////////////\r
9 // Global function in the ShellWrapper namespace\r
10 //\r
11 \r
12 namespace ShellWrapper\r
13 {\r
14         ///////////////////////////////////\r
15         //global functionnct definitions (within this namespace)\r
16         BOOL GetFullFileName(LPCITEMIDLIST pidlFull, LPTSTR pszPathName)\r
17         {\r
18                 if (!::SHGetPathFromIDList(pidlFull, pszPathName))\r
19                 {\r
20                         pszPathName[0] = _T('\0');\r
21                         return FALSE;\r
22                 }\r
23 \r
24                 return TRUE;\r
25         }\r
26 \r
27         BOOL GetDisplayName(LPCITEMIDLIST pidlFull, LPTSTR pszDisplayName)\r
28         {\r
29                 SHFILEINFO     sfi;\r
30 \r
31                 // Get the display name of the item\r
32                 if(!::SHGetFileInfo((LPCTSTR)pidlFull, 0, &sfi, sizeof(sfi), SHGFI_PIDL | SHGFI_DISPLAYNAME))\r
33                 {\r
34                         pszDisplayName[0] = _T('\0');\r
35                         return FALSE;\r
36                 }\r
37 \r
38                 ::lstrcpyn(pszDisplayName, sfi.szDisplayName, MAX_PATH -1);\r
39                 return TRUE;\r
40         }\r
41 \r
42 \r
43         ///////////////////////////////////\r
44         //CContextMenu function definitions\r
45         CContextMenu::CContextMenu() : m_pIContextMenu(NULL)\r
46         {\r
47         }\r
48 \r
49         CContextMenu::~CContextMenu()\r
50         {\r
51                 if (m_pIContextMenu)\r
52                         m_pIContextMenu->Release();\r
53         }\r
54 \r
55         void CContextMenu::Attach(IContextMenu* pIContextMenu)\r
56         {\r
57                 if (m_pIContextMenu)\r
58                         m_pIContextMenu->Release();\r
59                 m_pIContextMenu = pIContextMenu;\r
60         }\r
61 \r
62         HRESULT CContextMenu::InvokeCommand(CMINVOKECOMMANDINFO& Ici)\r
63         {\r
64                 HRESULT hr = m_pIContextMenu->InvokeCommand(&Ici);\r
65 \r
66                 if (hr != NOERROR)\r
67                 {\r
68                         TRACE(_T("CContextMenu::InvokeCommand failed\n"));\r
69                 }\r
70                 return hr;\r
71         }\r
72 \r
73         HRESULT CContextMenu::QueryInterface(REFIID iid, CContextMenu2& ccm2)\r
74         {\r
75                 HRESULT hr = 0;\r
76                 if (IID_IContextMenu2 == iid)\r
77                 {\r
78                         IContextMenu2* pIContextMenu2 = NULL;\r
79                         hr = m_pIContextMenu->QueryInterface(iid, (VOID**)&pIContextMenu2);\r
80                         if (S_OK == hr)\r
81                                 ccm2.Attach(pIContextMenu2);\r
82                         else\r
83                         {\r
84                                 TRACE(_T("CContextMenu::QueryInterface failed\n"));\r
85                         }\r
86                 }\r
87                 else\r
88                         TRACE(_T("Not Implemented!\n"));\r
89 \r
90                 return hr;\r
91         }\r
92 \r
93         HRESULT CContextMenu::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)\r
94         {\r
95                 HRESULT hr = m_pIContextMenu->QueryContextMenu(hmenu, indexMenu, idCmdFirst, idCmdLast, uFlags) ;\r
96                 if(hr & 0x80000000)\r
97                 {\r
98                         TRACE(_T("CContextMenu::QueryContextMenu failed\n"));\r
99                 }\r
100                 return hr;\r
101         }\r
102 \r
103 \r
104         ////////////////////////////////////\r
105         //CContextMenu2 function definitions\r
106         CContextMenu2::CContextMenu2() : m_pIContextMenu2(NULL)\r
107         {\r
108         }\r
109 \r
110         CContextMenu2::~CContextMenu2()\r
111         {\r
112                 if (m_pIContextMenu2)\r
113                         m_pIContextMenu2->Release();\r
114         }\r
115 \r
116         void CContextMenu2::Attach(IContextMenu2* pIContextMenu2)\r
117         {\r
118                 if (m_pIContextMenu2)\r
119                         m_pIContextMenu2->Release();\r
120                 m_pIContextMenu2 = pIContextMenu2;\r
121         }\r
122 \r
123         HRESULT CContextMenu2::HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam)\r
124         {\r
125                 HRESULT hr = m_pIContextMenu2->HandleMenuMsg(uMsg, wParam, lParam);\r
126 \r
127                 if((hr != S_OK) && (hr !=E_NOTIMPL))\r
128                 {\r
129                         TRACE(_T("CContextMenu2::HandleMenuMsg failed\n"));\r
130                 }\r
131 \r
132                 return hr;\r
133         }\r
134 \r
135         void CContextMenu2::Release()\r
136         {\r
137                 m_pIContextMenu2->Release();\r
138                 m_pIContextMenu2 = 0;\r
139         }\r
140 \r
141 \r
142         ///////////////////////////////////\r
143         //CShellFolder function definitions\r
144         CShellFolder::CShellFolder() : m_IShellFolder(NULL)\r
145         {\r
146         }\r
147 \r
148         CShellFolder::CShellFolder(const CShellFolder& csfSource) : m_IShellFolder(NULL)\r
149         {\r
150                 Copy(csfSource);\r
151         }\r
152 \r
153         void CShellFolder::operator=(const CShellFolder& csfSource)\r
154         {\r
155                 Copy(csfSource);\r
156         }\r
157 \r
158         CShellFolder::~CShellFolder()\r
159         {\r
160                 Delete();\r
161         }\r
162 \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
167         {\r
168                 Delete();\r
169                 m_IShellFolder = IShellFolder;\r
170         }\r
171 \r
172         HRESULT CShellFolder::BindToObject(const Cpidl& cpidl, LPBC pbc, REFIID riid, CShellFolder& NewFolder)\r
173         {\r
174                 LPSHELLFOLDER FolderTemp;\r
175                 LPITEMIDLIST pidl = cpidl.GetPidl();\r
176 \r
177                 HRESULT hr = m_IShellFolder->BindToObject(pidl, pbc, riid, (VOID**)&FolderTemp);\r
178                 if(S_OK == hr)\r
179                         NewFolder.Attach(FolderTemp);\r
180                 else\r
181                 {\r
182                         TRACE(_T("CShellFolder::BindToObject failed\n"));\r
183                 }\r
184 \r
185                 return hr;\r
186         }\r
187 \r
188         HRESULT CShellFolder::CompareIDs(LPARAM lParam, const Cpidl& cpidl1, const Cpidl& cpidl2)\r
189         {\r
190                 LPITEMIDLIST pidl1 = cpidl1.GetPidl();\r
191                 LPITEMIDLIST pidl2 = cpidl2.GetPidl();\r
192                 return m_IShellFolder->CompareIDs(lParam, pidl1, pidl2);\r
193         }\r
194 \r
195         void CShellFolder::Copy(LPSHELLFOLDER Source)\r
196         //Assigns the value to the CShellFolder object.\r
197         {\r
198                 Delete(); //Release the current m_IShellFolder\r
199                 m_IShellFolder = Source;\r
200                 if (Source) \r
201                         AddRef();\r
202         }\r
203 \r
204         void CShellFolder::Copy(const CShellFolder& Source)\r
205         //Assigns the value to the CShellFolder object.\r
206         {\r
207                 Delete(); //Release the current m_IShellFolder\r
208                 m_IShellFolder = Source.m_IShellFolder;\r
209                 if (Source.m_IShellFolder)\r
210                         AddRef();\r
211         }\r
212 \r
213         HRESULT CShellFolder::CreateViewObject(HWND hwnd, REFIID riid, CContextMenu& ccm)\r
214         {\r
215                 IContextMenu* pcm;\r
216                 HRESULT hr = m_IShellFolder->CreateViewObject(hwnd, riid, (LPVOID*)&pcm);\r
217                 if (S_OK == hr)\r
218                         ccm.Attach(pcm);\r
219                 else\r
220                 {\r
221                         TRACE(_T("CShellFolder::CreateViewObject failed\n"));\r
222                 }\r
223                 return hr;\r
224         }\r
225 \r
226         HRESULT CShellFolder::EnumObjects(HWND hwndOwner, int grfFlags, CEnumIDList& cenumIDList)\r
227         {\r
228                 LPENUMIDLIST pEnum;\r
229                 HRESULT hr = 0;\r
230                 if (m_IShellFolder)\r
231                 {\r
232                         hr = m_IShellFolder->EnumObjects(hwndOwner, grfFlags, &pEnum);\r
233                         if (S_OK == hr)\r
234                                 cenumIDList.Attach(pEnum);\r
235                         else\r
236                                 TRACE(_T("CShellFolder::EnumObjects failed\n"));\r
237                 }\r
238                 else\r
239                         TRACE(_T("CShellFolder::EnumObjects failed\n"));\r
240 \r
241                 return hr;\r
242         }\r
243 \r
244         HRESULT CShellFolder::GetAttributesOf(UINT cidl, const Cpidl& cpidl, ULONG& rgfInOut)\r
245         {\r
246                 LPCITEMIDLIST pidl = cpidl.GetPidl();\r
247                 HRESULT hr = m_IShellFolder->GetAttributesOf(cidl, &pidl, &rgfInOut);\r
248 \r
249                 if (hr != S_OK)\r
250                 {\r
251                         TRACE(_T("CShellFolder::GetAttributesOf failed\n"));\r
252                 }\r
253                 return hr;\r
254         }\r
255 \r
256         HRESULT CShellFolder::SHGetDesktopFolder()\r
257         {\r
258                 HRESULT hr = ::SHGetDesktopFolder(&m_IShellFolder);\r
259 \r
260                 if (hr != NOERROR)\r
261                 {\r
262                         TRACE(_T("CShellFolder::SHGetDesktopFolder failed\n"));\r
263                 }\r
264                 return hr;\r
265         }\r
266 \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
269         {\r
270                 LPCITEMIDLIST* pPidlArray;\r
271                 pPidlArray = (LPCITEMIDLIST*)::CoTaskMemAlloc(sizeof(LPITEMIDLIST) * nItems);\r
272                 if(!pPidlArray) return 0;\r
273 \r
274                 for(UINT i = 0; i < nItems; i++)\r
275                         pPidlArray[i] = cpidlArray[i].GetPidl();\r
276 \r
277                 IContextMenu* ppv;\r
278                 HRESULT hr = m_IShellFolder->GetUIObjectOf(hwndOwner, nItems, pPidlArray, riid, &rgfReserved, (VOID**)&ppv);\r
279 \r
280                 if (S_OK == hr)\r
281                         cm.Attach(ppv);\r
282                 else\r
283                 {\r
284                         TRACE(_T("CShellFolder::GetUIObjectOf failed\n"));\r
285                 }\r
286 \r
287                 CoTaskMemFree(pPidlArray);\r
288                 return hr;\r
289         }\r
290 \r
291         //Deletes the memory allocated for m_IShellFolder (if any)\r
292         void CShellFolder::Delete()\r
293         {\r
294                 if (m_IShellFolder)\r
295                         m_IShellFolder->Release();\r
296                 m_IShellFolder = NULL;\r
297         }\r
298 \r
299 \r
300         //////////////////////////////////\r
301         //CEnumIDList function definitions\r
302         CEnumIDList::CEnumIDList() : m_pEnumIDList(NULL)\r
303         {\r
304         }\r
305 \r
306         CEnumIDList::~CEnumIDList()\r
307         {\r
308                 if (m_pEnumIDList)\r
309                         m_pEnumIDList->Release();\r
310         }\r
311 \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
315         {\r
316                 m_pEnumIDList = EnumList;\r
317         }\r
318 \r
319         HRESULT CEnumIDList::Next(ULONG Elements, Cpidl& cpidl, ULONG& ulFetched)\r
320         {\r
321                 LPITEMIDLIST pidl;\r
322                 if (m_pEnumIDList)\r
323                 {\r
324                         HRESULT hr = m_pEnumIDList->Next(Elements, &pidl, &ulFetched);\r
325                         if (NOERROR == hr)\r
326                                 cpidl.Attach(pidl);\r
327 \r
328                         if ((NOERROR != hr) && (S_FALSE != hr))\r
329                         {\r
330                                 TRACE(_T("CEnumIDList::Next failed\n"));\r
331                         }\r
332                         return hr;\r
333                 }\r
334                 else\r
335                         return S_FALSE;\r
336         }\r
337 \r
338         //Cpidl function definitions\r
339         Cpidl::Cpidl() : m_pidl(NULL), m_pidlParent(NULL)\r
340         {\r
341                 ::SHGetMalloc(&m_pMalloc);\r
342         }\r
343 \r
344         Cpidl::Cpidl(const Cpidl& cpidlSource) : m_pidl(NULL), m_pidlParent(NULL)\r
345         {\r
346                 ::SHGetMalloc(&m_pMalloc);\r
347                 Copy(cpidlSource);\r
348         }\r
349 \r
350         void Cpidl::operator= (const Cpidl& cpidlSource)\r
351         {\r
352                 Copy(cpidlSource);\r
353         }\r
354 \r
355         BOOL Cpidl::operator== (const Cpidl& cpidl)\r
356         {\r
357                 return IsEqual(cpidl);\r
358         }\r
359 \r
360         const Cpidl operator+ (const Cpidl& cpidlFull, const Cpidl& cpidlRel)\r
361         {\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
365                 Cpidl Temp;\r
366                 Temp.Concatenate(cpidlFull, cpidlRel);\r
367                 return Temp;\r
368         }\r
369 \r
370         Cpidl::~Cpidl()\r
371         {\r
372                 Delete();\r
373                 if (m_pidlParent)\r
374                         m_pMalloc->Free(m_pidlParent);\r
375 \r
376                 m_pMalloc->Release();\r
377         }\r
378 \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
383         {\r
384                 Delete();  //Release the memory for m_pidl\r
385                 m_pidl = (LPITEMIDLIST)pidl;\r
386         }\r
387 \r
388         void Cpidl::Delete()\r
389         {\r
390                 if (m_pidl)\r
391                         m_pMalloc->Free(m_pidl);\r
392                 m_pidl = NULL;\r
393         }\r
394 \r
395         HRESULT Cpidl::SHGetSpecialFolderLocation(HWND hwnd, int csidl)\r
396         {\r
397                 Delete(); //Release the memory for m_pidl\r
398                 HRESULT hr = ::SHGetSpecialFolderLocation(hwnd, csidl, &m_pidl);\r
399                 if (hr != S_OK)\r
400                 {\r
401                         TRACE(_T("Cpidl::SHGetSpecialFolderLocation failed\n"));\r
402                 }\r
403                 return hr;\r
404         }\r
405 \r
406         DWORD_PTR Cpidl::SHGetFileInfo(DWORD dwFileAttributes, SHFILEINFO& sfi, UINT uFlags)\r
407         {\r
408                 LPITEMIDLIST pidl = m_pidl;\r
409                 return (DWORD_PTR)::SHGetFileInfo((LPCTSTR)pidl, dwFileAttributes, &sfi, sizeof(SHFILEINFO), uFlags);\r
410         }\r
411 \r
412         void Cpidl::Copy(const Cpidl& cpidlSource)\r
413         //The Cpidl object stores a copy of the pidlSource's m_pidl.\r
414         {\r
415                 Copy(cpidlSource.GetPidl());\r
416         }\r
417 \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
421         {\r
422                 UINT cbSource;\r
423                 Delete(); //Release the memory for m_pidl\r
424 \r
425                 if(NULL == pidlSource) return;\r
426 \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
431 \r
432                 ::CopyMemory(m_pidl, pidlSource, cbSource);\r
433         }\r
434 \r
435         LPITEMIDLIST Cpidl::GetParent()\r
436         {\r
437         // Delete m_pidlParent\r
438                 UINT nSize = GetSize(m_pidl);\r
439                 if (m_pidlParent)\r
440                         m_pMalloc->Free(m_pidlParent);\r
441                 m_pidlParent = NULL;\r
442 \r
443         // Make sure it's a valid PIDL.\r
444                 if (NULL == m_pidl)\r
445                         return(NULL);\r
446 \r
447         // Copy m_pidl to m_pidlParent\r
448                 m_pidlParent = (LPITEMIDLIST)m_pMalloc->Alloc(nSize);\r
449                 if (!m_pidlParent)\r
450                         return NULL;\r
451 \r
452                 ::CopyMemory(m_pidlParent, m_pidl, nSize);\r
453 \r
454         // Identify the last item's position\r
455                 if (m_pidlParent->mkid.cb)\r
456                 {\r
457                         LPITEMIDLIST pidlNext = m_pidlParent;\r
458                         LPITEMIDLIST pidlTemp = m_pidlParent;\r
459 \r
460                         while (pidlNext->mkid.cb)\r
461                         {\r
462                                 pidlTemp = pidlNext;\r
463                                 pidlNext = GetNextItem(pidlTemp);\r
464                         }\r
465                         // Remove the last item, set it's size to 0.\r
466                         pidlTemp->mkid.cb = 0;\r
467                 }\r
468                 return m_pidlParent;\r
469         }\r
470 \r
471         LPITEMIDLIST Cpidl::GetRelative()\r
472         //Stores a copy of the relative pidl obtained from a fully qualified pidl source.\r
473         {\r
474                 if(NULL == m_pidl) return NULL;\r
475 \r
476                 LPITEMIDLIST pidlNext = m_pidl;\r
477                 LPITEMIDLIST pidlRel  = m_pidl;\r
478 \r
479                 while( pidlNext->mkid.cb )\r
480                 {\r
481                         pidlNext = GetNextItem(pidlNext);\r
482                         if (pidlNext->mkid.cb)\r
483                                 pidlRel = (LPITEMIDLIST)pidlNext;\r
484                 }\r
485 \r
486                 UINT nPos = GetSize(m_pidl) - GetSize(pidlRel);\r
487                 return (LPITEMIDLIST)((LPBYTE)m_pidl + nPos);\r
488         }\r
489 \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
493         {\r
494                 Concatenate(cpidlParent.GetPidl(), cpidlRel.GetPidl());\r
495         }\r
496 \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
500         {\r
501                 UINT cb1 = 0;\r
502                 UINT cb2;\r
503 \r
504                 Delete(); //Release the current m_pidl\r
505 \r
506                 if (!pidlRel) return; //pidlRel should not be NULL\r
507 \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
510                 if(pidlParent)\r
511                         cb1 = GetSize(pidlParent) - (2 * sizeof(BYTE));\r
512 \r
513                 cb2 = GetSize(pidlRel);\r
514 \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
518                 if (m_pidl)\r
519                 {\r
520                         ::ZeroMemory(m_pidl, cb1 + cb2);\r
521                         if (pidlParent)\r
522                                 ::CopyMemory(m_pidl, pidlParent, cb1);\r
523 \r
524                         ::CopyMemory(((LPBYTE)m_pidl) + cb1, pidlRel, cb2);\r
525                 }\r
526         }\r
527 \r
528         UINT Cpidl::GetSize(LPCITEMIDLIST pidl)\r
529         {\r
530                 UINT cbTotal = 0;\r
531                 if (!pidl) return 0;\r
532 \r
533                 while(pidl)\r
534                 {\r
535                         cbTotal += pidl->mkid.cb;\r
536                         pidl = GetNextItem(pidl);\r
537                 }\r
538 \r
539                 // Requires a 16 bit zero value for the NULL terminator\r
540                 cbTotal += 2 * sizeof(BYTE);\r
541 \r
542                 return cbTotal;\r
543         }\r
544 \r
545         LPITEMIDLIST Cpidl::GetNextItem(LPCITEMIDLIST pidl)\r
546         {\r
547                 // Check for valid pidl.\r
548                 if(NULL == pidl)\r
549                         return NULL;\r
550 \r
551                 // Get the size of the specified item identifier.\r
552                 int cb = pidl->mkid.cb;\r
553 \r
554                 // If the size is zero, it is the end of the list.\r
555                 if (0 == cb)\r
556                         return NULL;\r
557 \r
558                 // Add cb to pidl (casting to increment by bytes).\r
559                 return (LPITEMIDLIST) (((LPBYTE) pidl) + cb);\r
560         }\r
561 \r
562         BOOL Cpidl::IsEqual(const Cpidl &cpidl)\r
563         {\r
564                 CShellFolder sf;\r
565                 sf.SHGetDesktopFolder();\r
566                 return (0 == sf.CompareIDs(0, *this, cpidl) );\r
567         }\r
568 }\r

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