Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

440 lines
11 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: I E X T R A C T . C P P
  7. //
  8. // Contents: IExtract implementation for CConnectionFolderExtractIcon
  9. //
  10. // Notes:
  11. //
  12. // Author: jeffspr 7 Oct 1997
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include "foldinc.h" // Standard shell\folder includes
  18. #include <nsres.h>
  19. #include "foldres.h"
  20. #include "iconhandler.h"
  21. static const WCHAR c_szNetShellIcon[] = L"netshellicon";
  22. HRESULT CConnectionFolderExtractIcon::CreateInstance(
  23. LPCITEMIDLIST apidl,
  24. REFIID riid,
  25. void** ppv)
  26. {
  27. TraceFileFunc(ttidShellFolderIface);
  28. HRESULT hr = E_OUTOFMEMORY;
  29. CConnectionFolderExtractIcon * pObj = NULL;
  30. pObj = new CComObject <CConnectionFolderExtractIcon>;
  31. if (pObj)
  32. {
  33. // Do the standard CComCreator::CreateInstance stuff.
  34. //
  35. pObj->SetVoid (NULL);
  36. pObj->InternalFinalConstructAddRef ();
  37. hr = pObj->FinalConstruct ();
  38. pObj->InternalFinalConstructRelease ();
  39. if (SUCCEEDED(hr))
  40. {
  41. PCONFOLDPIDL pcfp;
  42. hr = pcfp.InitializeFromItemIDList(apidl);
  43. if (SUCCEEDED(hr))
  44. {
  45. hr = pObj->HrInitialize(pcfp);
  46. if (SUCCEEDED(hr))
  47. {
  48. hr = pObj->GetUnknown()->QueryInterface (riid, ppv);
  49. }
  50. }
  51. }
  52. if (FAILED(hr))
  53. {
  54. delete pObj;
  55. }
  56. }
  57. return hr;
  58. }
  59. CConnectionFolderExtractIcon::CConnectionFolderExtractIcon()
  60. {
  61. TraceFileFunc(ttidShellFolderIface);
  62. }
  63. CConnectionFolderExtractIcon::~CConnectionFolderExtractIcon()
  64. {
  65. TraceFileFunc(ttidShellFolderIface);
  66. }
  67. HRESULT CConnectionFolderExtractIcon::HrInitialize(
  68. const PCONFOLDPIDL& pidl)
  69. {
  70. TraceFileFunc(ttidShellFolderIface);
  71. HRESULT hr = S_FALSE;
  72. ConnListEntry cle;
  73. if (SUCCEEDED(hr))
  74. {
  75. hr = g_ccl.HrFindConnectionByGuid(&(pidl->guidId), cle);
  76. }
  77. if (hr == S_OK)
  78. {
  79. Assert(!cle.empty());
  80. Assert(!cle.ccfe.empty());
  81. hr = cle.ccfe.ConvertToPidl(m_pidl);
  82. }
  83. else
  84. {
  85. // Couldn't find the icon in the cache.. Good chance that it hasn't been loaded
  86. // yet. That being the case, go ahead and use the persisted pidl data to
  87. // load the icon
  88. //
  89. TraceTag(ttidShellFolderIface, "IExtractIcon - Couldn't find connection in the cache.");
  90. hr = m_pidl.ILClone(pidl);
  91. }
  92. TraceHr(ttidShellFolderIface, FAL, hr, FALSE, "CConnectionFolderExtractIcon::HrInitialize");
  93. return hr;
  94. }
  95. //+---------------------------------------------------------------------------
  96. ////
  97. //// Function: HrLoadBrandedIcons
  98. ////
  99. //// Purpose: Load the branded icons from the specified files
  100. ////
  101. //// Arguments:
  102. //// cle [in] Our connlist entry structure
  103. //// dwIconSize [in] Size of icon requested
  104. //// phicon [out] Out param for icon
  105. ////
  106. //// Returns:
  107. ////
  108. //// Author: jeffspr 21 May 1998
  109. ////
  110. //// Notes:
  111. ////
  112. //HRESULT HrLoadBrandedIcons(
  113. // const ConnListEntry& cle,
  114. // HICON *phicon,
  115. // DWORD dwIconSize)
  116. //{
  117. // TraceFileFunc(ttidShellFolderIface);
  118. //
  119. // Assert(phicon);
  120. //
  121. // if (!phicon)
  122. // {
  123. // return E_INVALIDARG;
  124. // }
  125. //
  126. // HRESULT hr = S_OK;
  127. //
  128. // if (cle.pcbi->szwLargeIconPath)
  129. // {
  130. // *phicon = (HICON) LoadImage(
  131. // NULL,
  132. // cle.pcbi->szwLargeIconPath,
  133. // IMAGE_ICON,
  134. // dwIconSize, dwIconSize,
  135. // LR_LOADFROMFILE);
  136. //
  137. // if (!*phicon)
  138. // {
  139. // hr = E_FAIL;
  140. // }
  141. // }
  142. // else
  143. // {
  144. // hr = E_FAIL;
  145. // }
  146. //
  147. // TraceHr(ttidShellFolder, FAL, hr, FALSE, "HrLoadBrandedIcons");
  148. // return hr;
  149. //}
  150. //+---------------------------------------------------------------------------
  151. //
  152. // Member: CConnectionFolderExtractIcon::GetIconLocation
  153. //
  154. // Purpose:
  155. //
  156. // Arguments:
  157. // uFlags [in] Address of a UINT value that receives zero or a
  158. // combination of the following values:
  159. //
  160. // GIL_ASYNC The calling application supports asynchronous
  161. // retrieval of icons.
  162. // GIL_FORSHELL The icon is to be displayed in a shell folder.
  163. //
  164. // wzIconFile [out] Address of the buffer that receives the icon
  165. // location. The icon location is a null-terminated
  166. // string that identifies the file that contains
  167. // the icon.
  168. // cchMax [in] Size of the buffer that receives the icon location.
  169. // piIndex [out] Address of an INT that receives the icon index,
  170. // which further describes the icon location.
  171. // pwFlags [in] Address of a UINT value that receives zero or a
  172. // combination of the following values:
  173. //
  174. // GIL_DONTCACHE Don't cache the physical bits.
  175. // GIL_NOTFILENAME This isn't a filename/index pair. Call
  176. // IExtractIcon::Extract instead
  177. // GIL_PERCLASS (Only internal to the shell)
  178. // GIL_PERINSTANCE Each object of this class has the same icon.
  179. // GIL_FORSHORTCUT The icon is to be used for a shortcut.
  180. //
  181. //
  182. // Returns: S_OK if the function returned a valid location,
  183. // or S_FALSE if the shell should use a default icon.
  184. //
  185. // Author: jeffspr 25 Nov 1998
  186. //
  187. // Notes:
  188. //
  189. STDMETHODIMP CConnectionFolderExtractIcon::GetIconLocation(
  190. UINT uFlags,
  191. PWSTR szIconFile,
  192. UINT cchMax,
  193. int * piIndex,
  194. UINT * pwFlags)
  195. {
  196. TraceFileFunc(ttidShellFolderIface);
  197. HRESULT hr = S_FALSE;
  198. Assert(pwFlags);
  199. Assert(szIconFile);
  200. Assert(piIndex);
  201. #ifdef DBG
  202. // Easy way to check if certain flags are set
  203. //
  204. BOOL fAsync = (uFlags & GIL_ASYNC);
  205. BOOL fForShell = (uFlags & GIL_FORSHELL);
  206. BOOL fOpenIcon = (uFlags & GIL_OPENICON);
  207. DWORD dwOldpwFlags = *pwFlags;
  208. #endif
  209. BOOL fIsWizard = FALSE;
  210. const PCONFOLDPIDL& pcfp = m_pidl;
  211. Assert(!pcfp.empty());
  212. if (!pcfp.empty())
  213. {
  214. BOOL fCacheThisIcon = TRUE;
  215. CConFoldEntry cfe;
  216. hr = pcfp.ConvertToConFoldEntry(cfe);
  217. if (SUCCEEDED(hr))
  218. {
  219. DWORD dwIcon;
  220. hr = g_pNetConfigIcons->HrGetIconIDForPIDL(uFlags, cfe, dwIcon, &fCacheThisIcon);
  221. if (SUCCEEDED(hr))
  222. {
  223. *piIndex = static_cast<int>(dwIcon);
  224. wcsncpy(szIconFile, c_szNetShellIcon, cchMax);
  225. *pwFlags = GIL_PERINSTANCE | GIL_NOTFILENAME;
  226. if (!fCacheThisIcon)
  227. {
  228. *pwFlags |= GIL_DONTCACHE;
  229. }
  230. }
  231. }
  232. }
  233. #ifdef DBG
  234. TraceTag(ttidIcons, "%S->GetIconLocation(0x%04x/0x%04x,%S,0x%08x,0x%08x)", pcfp->PszGetNamePointer(), uFlags, dwOldpwFlags, szIconFile, *piIndex, *pwFlags);
  235. #endif
  236. return hr;
  237. }
  238. //+---------------------------------------------------------------------------
  239. //
  240. // Member: CConnectionFolderExtractIcon::GetIconLocation
  241. //
  242. // Purpose: ANSI wrapper for the above UNICODE GetIconLocation
  243. //
  244. // Arguments:
  245. // uFlags [] See above
  246. // szIconFile [] See above
  247. // cchMax [] See above
  248. // piIndex [] See above
  249. // pwFlags [] See above
  250. //
  251. // Returns:
  252. //
  253. // Author: jeffspr 6 Apr 1999
  254. //
  255. // Notes:
  256. //
  257. STDMETHODIMP CConnectionFolderExtractIcon::GetIconLocation(
  258. UINT uFlags,
  259. PSTR szIconFile,
  260. UINT cchMax,
  261. int * piIndex,
  262. UINT * pwFlags)
  263. {
  264. TraceFileFunc(ttidShellFolderIface);
  265. HRESULT hr = S_OK;
  266. WCHAR * pszIconFileW = new WCHAR[cchMax];
  267. if (!pszIconFileW)
  268. {
  269. hr = ERROR_OUTOFMEMORY;
  270. }
  271. else
  272. {
  273. hr = GetIconLocation(uFlags, pszIconFileW, cchMax, piIndex, pwFlags);
  274. if (SUCCEEDED(hr))
  275. {
  276. WideCharToMultiByte(CP_ACP, 0, pszIconFileW, -1, szIconFile, cchMax, NULL, NULL);
  277. }
  278. delete [] pszIconFileW;
  279. }
  280. TraceHr(ttidShellFolder, FAL, hr, FALSE, "CConnectionFolderExtractIcon::GetIconLocation(A)");
  281. return hr;
  282. }
  283. //+---------------------------------------------------------------------------
  284. //
  285. // Member: CConnectionFolderExtractIcon::Extract
  286. //
  287. // Purpose: Grab the actual icon for the caller.
  288. //
  289. // Arguments:
  290. // wzFile [] Filename from where we'll retrieve the icon
  291. // nIconIndex [] Index of the icon (though this is bogus)
  292. // phiconLarge [] Return pointer for the large icon handle
  293. // phiconSmall [] Return pointer for the small icon handle
  294. // nIconSize [] Size of the icon requested.
  295. //
  296. // Returns:
  297. //
  298. // Author: jeffspr 9 Oct 1997
  299. //
  300. // Notes:
  301. //
  302. STDMETHODIMP CConnectionFolderExtractIcon::Extract(
  303. PCWSTR wzFile,
  304. UINT nIconIndex,
  305. HICON * phiconLarge,
  306. HICON * phiconSmall,
  307. UINT nIconSize)
  308. {
  309. TraceFileFunc(ttidShellFolderIface);
  310. HRESULT hr = S_OK;
  311. ConnListEntry cle;
  312. Assert(wzFile);
  313. Assert(phiconLarge);
  314. Assert(phiconSmall);
  315. if (wcscmp(wzFile, c_szNetShellIcon))
  316. {
  317. TraceHr(ttidError, FAL, E_INVALIDARG, FALSE, "This is not my icon.");
  318. return E_INVALIDARG;
  319. }
  320. Assert(!m_pidl.empty());
  321. DWORD dwIconLargeSize = LOWORD(nIconSize);
  322. DWORD dwIconSmallSize = HIWORD(nIconSize);
  323. hr = g_pNetConfigIcons->HrGetIconFromIconId(dwIconSmallSize, nIconIndex, *phiconSmall);
  324. if (SUCCEEDED(hr))
  325. {
  326. hr = g_pNetConfigIcons->HrGetIconFromIconId(dwIconLargeSize, nIconIndex, *phiconLarge);
  327. if (FAILED(hr))
  328. {
  329. DestroyIcon(*phiconSmall);
  330. *phiconSmall = NULL;
  331. *phiconLarge = NULL;
  332. }
  333. }
  334. else
  335. {
  336. *phiconSmall = NULL;
  337. *phiconLarge = NULL;
  338. }
  339. TraceTag(ttidIcons, "%S,0x%08x->Extract(%d %d)", wzFile, nIconIndex, dwIconLargeSize, dwIconSmallSize);
  340. return hr;
  341. }
  342. //+---------------------------------------------------------------------------
  343. //
  344. // Member: CConnectionFolderExtractIcon::Extract
  345. //
  346. // Purpose: ANSI version of the above Extract
  347. //
  348. // Arguments:
  349. // pszFile [] Filename from where we'll retrieve the icon
  350. // nIconIndex [] Index of the icon (though this is bogus)
  351. // phiconLarge [] Return pointer for the large icon handle
  352. // phiconSmall [] Return pointer for the small icon handle
  353. // nIconSize [] Size of the icon requested.
  354. //
  355. // Returns:
  356. //
  357. // Author: jeffspr 6 Apr 1999
  358. //
  359. // Notes:
  360. //
  361. STDMETHODIMP CConnectionFolderExtractIcon::Extract(
  362. PCSTR pszFile,
  363. UINT nIconIndex,
  364. HICON * phiconLarge,
  365. HICON * phiconSmall,
  366. UINT nIconSize)
  367. {
  368. TraceFileFunc(ttidShellFolderIface);
  369. HRESULT hr = S_OK;
  370. INT cch = 0;
  371. WCHAR * pszFileW = NULL;
  372. Assert(pszFile);
  373. cch = lstrlenA(pszFile) + 1;
  374. pszFileW = new WCHAR[cch];
  375. if (!pszFileW)
  376. {
  377. hr = ERROR_OUTOFMEMORY;
  378. }
  379. else
  380. {
  381. MultiByteToWideChar(CP_ACP, 0, pszFile, -1, pszFileW, cch);
  382. hr = Extract(pszFileW, nIconIndex, phiconLarge, phiconSmall, nIconSize);
  383. delete [] pszFileW;
  384. }
  385. TraceHr(ttidShellFolder, FAL, hr, FALSE, "CConnectionFolderExtractIcon::Extract(A)");
  386. return hr;
  387. }