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.

422 lines
9.4 KiB

  1. //____________________________________________________________________________
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1999
  5. //
  6. // File: ScopImag.cpp
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 10/4/1996 RaviR Created
  15. //____________________________________________________________________________
  16. //
  17. #include "stdafx.h"
  18. #include "bitmap.h"
  19. #include "scopimag.h"
  20. #include "util.h"
  21. #ifdef _DEBUG
  22. #undef THIS_FILE
  23. static char THIS_FILE[] = __FILE__;
  24. #endif
  25. typedef WORD ICONID;
  26. typedef DWORD SNAPINICONID;
  27. typedef int ILINDEX; // image list index
  28. #define MAKESNAPINICONID(ICONID, SNAPINID) MAKELONG(ICONID, SNAPINID)
  29. #define GETSNAPINID(SNAPINICONID) ((int)(short)HIWORD(SNAPINICONID))
  30. #define GETICONID(SNAPINICONID) ((int)(short)LOWORD(SNAPINICONID))
  31. //______________________________________________________________________
  32. //______________________________________________________________________
  33. //______________________________________________________________________
  34. //______________________________________________________________________
  35. //
  36. class CGuidArrayEx : public CArray<GUID, REFGUID>
  37. {
  38. public:
  39. CGuidArrayEx() { SetSize(0, 10); }
  40. ~CGuidArrayEx() {}
  41. int Find(REFGUID refGuid);
  42. }; // class CGuidArrayEx
  43. static CGuidArrayEx s_GuidArray;
  44. int CGuidArrayEx::Find(REFGUID refGuid)
  45. {
  46. for (int i=0; i <= GetUpperBound(); i++)
  47. {
  48. if (IsEqualGUID(refGuid, (*this)[i]) == TRUE)
  49. return i;
  50. }
  51. return -1;
  52. }
  53. //______________________________________________________________________
  54. //______________________________________________________________________
  55. //______________________________________________________________________
  56. //______________________________________________________________________
  57. //
  58. DEBUG_DECLARE_INSTANCE_COUNTER(CSnapInImageList);
  59. CSnapInImageList::CSnapInImageList(
  60. CSPImageCache *pSPImageCache,
  61. REFGUID refGuidSnapIn)
  62. :
  63. m_ulRefs(1),
  64. m_pSPImageCache(pSPImageCache)
  65. {
  66. ASSERT(pSPImageCache != NULL);
  67. m_pSPImageCache = pSPImageCache;
  68. m_pSPImageCache->AddRef();
  69. int iRet = s_GuidArray.Find(refGuidSnapIn);
  70. if (iRet == -1)
  71. iRet = s_GuidArray.Add(refGuidSnapIn);
  72. m_snapInId = static_cast<WORD>(iRet);
  73. DEBUG_INCREMENT_INSTANCE_COUNTER(CSnapInImageList);
  74. }
  75. CSnapInImageList::~CSnapInImageList()
  76. {
  77. SAFE_RELEASE(m_pSPImageCache);
  78. DEBUG_DECREMENT_INSTANCE_COUNTER(CSnapInImageList);
  79. }
  80. // IUnknown methods
  81. STDMETHODIMP_(ULONG) CSnapInImageList::AddRef()
  82. {
  83. return InterlockedIncrement((LONG*)&m_ulRefs);
  84. }
  85. STDMETHODIMP_(ULONG) CSnapInImageList::Release()
  86. {
  87. ULONG ulRet = InterlockedDecrement((LONG*)&m_ulRefs);
  88. if (0 == ulRet)
  89. {
  90. delete this;
  91. }
  92. return ulRet;
  93. }
  94. STDMETHODIMP
  95. CSnapInImageList::QueryInterface(REFIID riid, LPVOID* ppvObj)
  96. {
  97. LPUNKNOWN punk = NULL;
  98. if (IsEqualIID(IID_IUnknown, riid) ||
  99. IsEqualIID(IID_IImageList, riid))
  100. {
  101. punk = (IUnknown*)(IImageList*) this;
  102. }
  103. else if (IsEqualIID(IID_IImageListPrivate, riid))
  104. {
  105. punk = (IUnknown*)(IImageListPrivate*) this;
  106. }
  107. else
  108. {
  109. *ppvObj = NULL;
  110. return E_NOINTERFACE;
  111. }
  112. *ppvObj = punk;
  113. punk->AddRef();
  114. return S_OK;
  115. }
  116. STDMETHODIMP
  117. CSnapInImageList::ImageListSetIcon(
  118. PLONG_PTR pIcon,
  119. LONG nLoc)
  120. {
  121. return m_pSPImageCache->SetIcon(m_snapInId, reinterpret_cast<HICON>(pIcon), nLoc);
  122. }
  123. STDMETHODIMP
  124. CSnapInImageList::ImageListSetStrip(
  125. PLONG_PTR pBMapSm,
  126. PLONG_PTR pBMapLg,
  127. LONG nStartLoc,
  128. COLORREF cMask)
  129. {
  130. BITMAP szSmall;
  131. ASSERT(pBMapSm != NULL);
  132. //HBITMAP hBMapSm = reinterpret_cast<HBITMAP>(pBMapSm);
  133. HBITMAP hBMapSm = (HBITMAP)pBMapSm;
  134. if (GetObject(hBMapSm, sizeof(BITMAP), &szSmall) == 0)
  135. {
  136. if (GetBitmapBits(hBMapSm, sizeof(BITMAP), &szSmall) == 0)
  137. {
  138. LRESULT lr = GetLastError();
  139. return HRESULT_FROM_WIN32(lr);
  140. }
  141. }
  142. int nEntries = szSmall.bmWidth/16;
  143. if ((szSmall.bmHeight != 16) || (szSmall.bmWidth % 16))
  144. return E_INVALIDARG;
  145. return (m_pSPImageCache->SetImageStrip (m_snapInId, (HBITMAP)pBMapSm,
  146. nStartLoc, cMask, nEntries));
  147. }
  148. STDMETHODIMP
  149. CSnapInImageList::MapRsltImage(
  150. COMPONENTID id,
  151. int nSnapinIndex,
  152. int *pnConsoleIndex)
  153. {
  154. DECLARE_SC (sc, _T("CSnapInImageList::MapRsltImage"));
  155. sc = ScCheckPointers (pnConsoleIndex);
  156. if (sc)
  157. return (sc.ToHr());
  158. sc = m_pSPImageCache->ScMapSnapinIndexToScopeIndex(m_snapInId, nSnapinIndex, *pnConsoleIndex);
  159. if (sc)
  160. return (sc.ToHr());
  161. return (sc.ToHr());
  162. }
  163. STDMETHODIMP
  164. CSnapInImageList::UnmapRsltImage(
  165. COMPONENTID id,
  166. int nConsoleIndex,
  167. int *pnSnapinIndex)
  168. {
  169. DECLARE_SC (sc, _T("CSnapInImageList::MapRsltImage"));
  170. sc = ScCheckPointers (pnSnapinIndex);
  171. if (sc)
  172. return (sc.ToHr());
  173. sc = m_pSPImageCache->ScMapScopeIndexToSnapinIndex(m_snapInId, nConsoleIndex, *pnSnapinIndex);
  174. if (sc)
  175. return (sc.ToHr());
  176. return (sc.ToHr());
  177. }
  178. //______________________________________________________________________
  179. //______________________________________________________________________
  180. //______________________________________________________________________
  181. //______________________________________________________________________
  182. //
  183. DEBUG_DECLARE_INSTANCE_COUNTER(CSPImageCache);
  184. CSPImageCache::CSPImageCache()
  185. :
  186. m_map(20),
  187. m_il(),
  188. m_cRef(1)
  189. {
  190. m_map.InitHashTable(223);
  191. BOOL fReturn = m_il.Create(16, 16, ILC_COLOR8 | ILC_MASK, 20, 10);
  192. ASSERT((fReturn != 0) && "Failed to create ImageList");
  193. DEBUG_INCREMENT_INSTANCE_COUNTER(CSPImageCache);
  194. }
  195. CSPImageCache::~CSPImageCache()
  196. {
  197. m_il.Destroy();
  198. ASSERT(m_cRef == 0);
  199. DEBUG_DECREMENT_INSTANCE_COUNTER(CSPImageCache);
  200. }
  201. HRESULT
  202. CSPImageCache::SetIcon(
  203. SNAPINID sid,
  204. HICON hIcon,
  205. LONG nLoc)
  206. {
  207. SNAPINICONID key = MAKESNAPINICONID(nLoc, sid);
  208. ULONG nNdx1;
  209. ULONG nNdx2;
  210. HRESULT hr = S_OK;
  211. //m_critSec.Lock(m_hWnd);
  212. if (m_map.Lookup(key, nNdx1))
  213. {
  214. nNdx2 = m_il.ReplaceIcon(nNdx1, hIcon);
  215. if (nNdx2 == -1)
  216. {
  217. hr = E_FAIL;
  218. CHECK_HRESULT(hr);
  219. }
  220. else if (nNdx2 != nNdx1)
  221. {
  222. hr = E_UNEXPECTED;
  223. CHECK_HRESULT(hr);
  224. }
  225. }
  226. else
  227. {
  228. // Add the icon to imagelist
  229. nNdx1 = m_il.AddIcon(hIcon);
  230. if (nNdx1 == -1)
  231. {
  232. hr = E_FAIL;
  233. CHECK_HRESULT(hr);
  234. }
  235. else
  236. {
  237. // Generate a new key and store the values in the maps
  238. m_map.SetAt(key, nNdx1);
  239. }
  240. }
  241. //m_critSec.Unlock();
  242. return hr;
  243. }
  244. HRESULT
  245. CSPImageCache::SetImageStrip(
  246. SNAPINID sid,
  247. HBITMAP hBMap,
  248. LONG nStartLoc,
  249. COLORREF cMask,
  250. int nEntries)
  251. {
  252. DECLARE_SC(sc, TEXT("CSPImageCache::SetImageStrip"));
  253. ULONG nNdx;
  254. // The CImageList::Add modifies the input bitmaps so make a copy first.
  255. WTL::CBitmap bmSmall;
  256. bmSmall.Attach(CopyBitmap(hBMap));
  257. if (bmSmall.IsNull())
  258. return (sc.FromLastError().ToHr());
  259. nNdx = m_il.Add( bmSmall, cMask);
  260. if (nNdx == -1)
  261. return (sc = E_FAIL).ToHr();
  262. // Keep the map updated for each newly inserted image.
  263. for (int i=0; i < nEntries; i++)
  264. {
  265. // REVIEW: review this part of the code.
  266. SNAPINICONID key = MAKESNAPINICONID(nStartLoc, sid);
  267. m_map.SetAt(key, nNdx);
  268. ++nStartLoc;
  269. ++nNdx;
  270. }
  271. return sc.ToHr();
  272. }
  273. /*+-------------------------------------------------------------------------*
  274. * ScMapSnapinIndexToScopeIndex
  275. *
  276. * Maps a snap-in's typically zero-based image index to an index for the
  277. * common scope tree image list
  278. *--------------------------------------------------------------------------*/
  279. SC CSPImageCache::ScMapSnapinIndexToScopeIndex (
  280. SNAPINID sid, // I:what snap-in is this for?
  281. int nSnapinIndex, // I:index by which the snap-in refers to the image
  282. int& nScopeIndex) // O:index by which the scope tree refers to the image
  283. {
  284. DECLARE_SC (sc, _T("ScMapSnapinIndexToScopeIndex"));
  285. SNAPINICONID key = MAKESNAPINICONID(nSnapinIndex, sid);
  286. ASSERT (GETSNAPINID (key) == sid);
  287. ASSERT (GETICONID (key) == nSnapinIndex);
  288. ULONG ul;
  289. if (!m_map.Lookup(key, ul))
  290. return (sc = E_FAIL);
  291. nScopeIndex = ul;
  292. return (sc);
  293. }
  294. /*+-------------------------------------------------------------------------*
  295. * ScMapScopeIndexToSnapinIndex
  296. *
  297. * Maps a scope tree image index to the given snap-in's image index.
  298. *--------------------------------------------------------------------------*/
  299. SC CSPImageCache::ScMapScopeIndexToSnapinIndex (
  300. SNAPINID sid, // I:what snap-in is this for?
  301. int nScopeIndex, // I:index by which the scope tree refers to the image
  302. int& nSnapinIndex) // O:index by which the snap-in refers to the image
  303. {
  304. DECLARE_SC (sc, _T("ScMapScopeIndexToSnapinIndex"));
  305. sc = E_FAIL; // assume failure
  306. /*
  307. * iterate through the map looking for scope indices matching the requested one
  308. */
  309. for (POSITION pos = m_map.GetStartPosition(); pos != NULL; )
  310. {
  311. SNAPINICONID key;
  312. DWORD value;
  313. m_map.GetNextAssoc (pos, key, value);
  314. /*
  315. * if this value matches the requested scope image index and it
  316. * belongs to the given snap-in, we've found a match; return it
  317. */
  318. if ((value == nScopeIndex) && (GETSNAPINID(key) == sid))
  319. {
  320. nSnapinIndex = GETICONID (key);
  321. sc = S_OK;
  322. break;
  323. }
  324. }
  325. return (sc);
  326. }