/3rd_party/wtl/Samples/WTLExplorer/ShellMgr.Cpp

https://code.google.com/p/softart/ · C++ · 173 lines · 138 code · 32 blank · 3 comment · 23 complexity · c0180279cef9dd30f268932b05acee52 MD5 · raw file

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