PageRenderTime 34ms CodeModel.GetById 30ms app.highlight 1ms RepoModel.GetById 1ms app.codeStats 0ms

/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
Possible License(s): LGPL-2.1, BSD-3-Clause, JSON, MPL-2.0-no-copyleft-exception, GPL-2.0, GPL-3.0, LGPL-3.0, BSD-2-Clause
  1// shellmgr.cpp
  2
  3#include "stdafx.h"
  4#include <atlctrls.h>
  5#include <atlctrlx.h>
  6
  7#include "shellmgr.h"
  8#include "mainfrm.h"
  9
 10
 11int CShellMgr::GetIconIndex(LPITEMIDLIST lpi, UINT uFlags)
 12{
 13	SHFILEINFO sfi = { 0 };
 14	DWORD_PTR dwRet = ::SHGetFileInfo((LPCTSTR)lpi, 0, &sfi, sizeof(SHFILEINFO), uFlags);
 15	return (dwRet != 0) ? sfi.iIcon : -1;
 16}
 17
 18void CShellMgr::GetNormalAndSelectedIcons(LPITEMIDLIST lpifq, LPTVITEM lptvitem)
 19{
 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);
 24}
 25
 26LPITEMIDLIST CShellMgr::ConcatPidls(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
 27{
 28	UINT cb1 = 0;
 29	if (pidl1 != NULL)   // May be NULL
 30		cb1 = GetSize(pidl1) - sizeof(pidl1->mkid.cb);
 31
 32	UINT cb2 = GetSize(pidl2);
 33
 34	LPITEMIDLIST pidlNew = (LPITEMIDLIST)::CoTaskMemAlloc(cb1 + cb2);
 35	if (pidlNew != NULL)
 36	{
 37		if (pidl1 != NULL)
 38			memcpy(pidlNew, pidl1, cb1);
 39
 40		memcpy(((LPSTR)pidlNew) + cb1, pidl2, cb2);
 41	}
 42
 43	return pidlNew;
 44}
 45
 46BOOL CShellMgr::GetName(LPSHELLFOLDER lpsf, LPITEMIDLIST lpi, DWORD dwFlags, LPTSTR lpFriendlyName)
 47{
 48	BOOL bSuccess = TRUE;
 49	STRRET str = { STRRET_CSTR };
 50
 51	if (lpsf->GetDisplayNameOf(lpi, dwFlags, &str) == NOERROR)
 52	{
 53		USES_CONVERSION;
 54
 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	}
 76
 77	return bSuccess;
 78}
 79
 80LPITEMIDLIST CShellMgr::Next(LPCITEMIDLIST pidl)
 81{
 82	LPSTR lpMem = (LPSTR)pidl;
 83	lpMem += pidl->mkid.cb;
 84	return (LPITEMIDLIST)lpMem;
 85}
 86
 87UINT CShellMgr::GetSize(LPCITEMIDLIST pidl)
 88{
 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	}
 99
100	return cbTotal;
101}
102
103LPITEMIDLIST CShellMgr::CopyITEMID(LPITEMIDLIST lpi)
104{
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;
108}
109
110LPITEMIDLIST CShellMgr::GetFullyQualPidl(LPSHELLFOLDER lpsf, LPITEMIDLIST lpi)
111{
112	TCHAR szBuff[MAX_PATH] = { 0 };
113
114	if (!GetName(lpsf, lpi, SHGDN_FORPARSING, szBuff))
115		return NULL;
116
117	CComPtr<IShellFolder> spDeskTop;
118	HRESULT hr = ::SHGetDesktopFolder(&spDeskTop);
119	if (FAILED(hr))
120		return NULL;
121
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);
127
128	if (FAILED(hr))
129		return NULL;
130
131	return lpifq;
132}
133
134BOOL CShellMgr::DoContextMenu(HWND hWnd, LPSHELLFOLDER lpsfParent, LPITEMIDLIST lpi, POINT point)
135{
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;
140
141	HMENU hMenu = ::CreatePopupMenu();
142	if(hMenu == NULL)
143		return FALSE;
144
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;
149
150	int idCmd = ::TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_RETURNCMD | TPM_RIGHTBUTTON, point.x, point.y, 0, hWnd, NULL);
151
152	if (idCmd != 0)
153	{
154		USES_CONVERSION;
155
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	}
169
170	::DestroyMenu(hMenu);
171
172	return TRUE;
173}