//____________________________________________________________________________ // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1996 - 1999 // // File: ScopImag.cpp // // Contents: // // Classes: // // Functions: // // History: 10/4/1996 RaviR Created //____________________________________________________________________________ // #include "stdafx.h" #include "bitmap.h" #include "scopimag.h" #include "util.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif typedef WORD ICONID; typedef DWORD SNAPINICONID; typedef int ILINDEX; // image list index #define MAKESNAPINICONID(ICONID, SNAPINID) MAKELONG(ICONID, SNAPINID) #define GETSNAPINID(SNAPINICONID) ((int)(short)HIWORD(SNAPINICONID)) #define GETICONID(SNAPINICONID) ((int)(short)LOWORD(SNAPINICONID)) //______________________________________________________________________ //______________________________________________________________________ //______________________________________________________________________ //______________________________________________________________________ // class CGuidArrayEx : public CArray { public: CGuidArrayEx() { SetSize(0, 10); } ~CGuidArrayEx() {} int Find(REFGUID refGuid); }; // class CGuidArrayEx static CGuidArrayEx s_GuidArray; int CGuidArrayEx::Find(REFGUID refGuid) { for (int i=0; i <= GetUpperBound(); i++) { if (IsEqualGUID(refGuid, (*this)[i]) == TRUE) return i; } return -1; } //______________________________________________________________________ //______________________________________________________________________ //______________________________________________________________________ //______________________________________________________________________ // DEBUG_DECLARE_INSTANCE_COUNTER(CSnapInImageList); CSnapInImageList::CSnapInImageList( CSPImageCache *pSPImageCache, REFGUID refGuidSnapIn) : m_ulRefs(1), m_pSPImageCache(pSPImageCache) { ASSERT(pSPImageCache != NULL); m_pSPImageCache = pSPImageCache; m_pSPImageCache->AddRef(); int iRet = s_GuidArray.Find(refGuidSnapIn); if (iRet == -1) iRet = s_GuidArray.Add(refGuidSnapIn); m_snapInId = static_cast(iRet); DEBUG_INCREMENT_INSTANCE_COUNTER(CSnapInImageList); } CSnapInImageList::~CSnapInImageList() { SAFE_RELEASE(m_pSPImageCache); DEBUG_DECREMENT_INSTANCE_COUNTER(CSnapInImageList); } // IUnknown methods STDMETHODIMP_(ULONG) CSnapInImageList::AddRef() { return InterlockedIncrement((LONG*)&m_ulRefs); } STDMETHODIMP_(ULONG) CSnapInImageList::Release() { ULONG ulRet = InterlockedDecrement((LONG*)&m_ulRefs); if (0 == ulRet) { delete this; } return ulRet; } STDMETHODIMP CSnapInImageList::QueryInterface(REFIID riid, LPVOID* ppvObj) { LPUNKNOWN punk = NULL; if (IsEqualIID(IID_IUnknown, riid) || IsEqualIID(IID_IImageList, riid)) { punk = (IUnknown*)(IImageList*) this; } else if (IsEqualIID(IID_IImageListPrivate, riid)) { punk = (IUnknown*)(IImageListPrivate*) this; } else { *ppvObj = NULL; return E_NOINTERFACE; } *ppvObj = punk; punk->AddRef(); return S_OK; } STDMETHODIMP CSnapInImageList::ImageListSetIcon( PLONG_PTR pIcon, LONG nLoc) { return m_pSPImageCache->SetIcon(m_snapInId, reinterpret_cast(pIcon), nLoc); } STDMETHODIMP CSnapInImageList::ImageListSetStrip( PLONG_PTR pBMapSm, PLONG_PTR pBMapLg, LONG nStartLoc, COLORREF cMask) { BITMAP szSmall; ASSERT(pBMapSm != NULL); //HBITMAP hBMapSm = reinterpret_cast(pBMapSm); HBITMAP hBMapSm = (HBITMAP)pBMapSm; if (GetObject(hBMapSm, sizeof(BITMAP), &szSmall) == 0) { if (GetBitmapBits(hBMapSm, sizeof(BITMAP), &szSmall) == 0) { LRESULT lr = GetLastError(); return HRESULT_FROM_WIN32(lr); } } int nEntries = szSmall.bmWidth/16; if ((szSmall.bmHeight != 16) || (szSmall.bmWidth % 16)) return E_INVALIDARG; return (m_pSPImageCache->SetImageStrip (m_snapInId, (HBITMAP)pBMapSm, nStartLoc, cMask, nEntries)); } STDMETHODIMP CSnapInImageList::MapRsltImage( COMPONENTID id, int nSnapinIndex, int *pnConsoleIndex) { DECLARE_SC (sc, _T("CSnapInImageList::MapRsltImage")); sc = ScCheckPointers (pnConsoleIndex); if (sc) return (sc.ToHr()); sc = m_pSPImageCache->ScMapSnapinIndexToScopeIndex(m_snapInId, nSnapinIndex, *pnConsoleIndex); if (sc) return (sc.ToHr()); return (sc.ToHr()); } STDMETHODIMP CSnapInImageList::UnmapRsltImage( COMPONENTID id, int nConsoleIndex, int *pnSnapinIndex) { DECLARE_SC (sc, _T("CSnapInImageList::MapRsltImage")); sc = ScCheckPointers (pnSnapinIndex); if (sc) return (sc.ToHr()); sc = m_pSPImageCache->ScMapScopeIndexToSnapinIndex(m_snapInId, nConsoleIndex, *pnSnapinIndex); if (sc) return (sc.ToHr()); return (sc.ToHr()); } //______________________________________________________________________ //______________________________________________________________________ //______________________________________________________________________ //______________________________________________________________________ // DEBUG_DECLARE_INSTANCE_COUNTER(CSPImageCache); CSPImageCache::CSPImageCache() : m_map(20), m_il(), m_cRef(1) { m_map.InitHashTable(223); BOOL fReturn = m_il.Create(16, 16, ILC_COLOR8 | ILC_MASK, 20, 10); ASSERT((fReturn != 0) && "Failed to create ImageList"); DEBUG_INCREMENT_INSTANCE_COUNTER(CSPImageCache); } CSPImageCache::~CSPImageCache() { m_il.Destroy(); ASSERT(m_cRef == 0); DEBUG_DECREMENT_INSTANCE_COUNTER(CSPImageCache); } HRESULT CSPImageCache::SetIcon( SNAPINID sid, HICON hIcon, LONG nLoc) { SNAPINICONID key = MAKESNAPINICONID(nLoc, sid); ULONG nNdx1; ULONG nNdx2; HRESULT hr = S_OK; //m_critSec.Lock(m_hWnd); if (m_map.Lookup(key, nNdx1)) { nNdx2 = m_il.ReplaceIcon(nNdx1, hIcon); if (nNdx2 == -1) { hr = E_FAIL; CHECK_HRESULT(hr); } else if (nNdx2 != nNdx1) { hr = E_UNEXPECTED; CHECK_HRESULT(hr); } } else { // Add the icon to imagelist nNdx1 = m_il.AddIcon(hIcon); if (nNdx1 == -1) { hr = E_FAIL; CHECK_HRESULT(hr); } else { // Generate a new key and store the values in the maps m_map.SetAt(key, nNdx1); } } //m_critSec.Unlock(); return hr; } HRESULT CSPImageCache::SetImageStrip( SNAPINID sid, HBITMAP hBMap, LONG nStartLoc, COLORREF cMask, int nEntries) { DECLARE_SC(sc, TEXT("CSPImageCache::SetImageStrip")); ULONG nNdx; // The CImageList::Add modifies the input bitmaps so make a copy first. WTL::CBitmap bmSmall; bmSmall.Attach(CopyBitmap(hBMap)); if (bmSmall.IsNull()) return (sc.FromLastError().ToHr()); nNdx = m_il.Add( bmSmall, cMask); if (nNdx == -1) return (sc = E_FAIL).ToHr(); // Keep the map updated for each newly inserted image. for (int i=0; i < nEntries; i++) { // REVIEW: review this part of the code. SNAPINICONID key = MAKESNAPINICONID(nStartLoc, sid); m_map.SetAt(key, nNdx); ++nStartLoc; ++nNdx; } return sc.ToHr(); } /*+-------------------------------------------------------------------------* * ScMapSnapinIndexToScopeIndex * * Maps a snap-in's typically zero-based image index to an index for the * common scope tree image list *--------------------------------------------------------------------------*/ SC CSPImageCache::ScMapSnapinIndexToScopeIndex ( SNAPINID sid, // I:what snap-in is this for? int nSnapinIndex, // I:index by which the snap-in refers to the image int& nScopeIndex) // O:index by which the scope tree refers to the image { DECLARE_SC (sc, _T("ScMapSnapinIndexToScopeIndex")); SNAPINICONID key = MAKESNAPINICONID(nSnapinIndex, sid); ASSERT (GETSNAPINID (key) == sid); ASSERT (GETICONID (key) == nSnapinIndex); ULONG ul; if (!m_map.Lookup(key, ul)) return (sc = E_FAIL); nScopeIndex = ul; return (sc); } /*+-------------------------------------------------------------------------* * ScMapScopeIndexToSnapinIndex * * Maps a scope tree image index to the given snap-in's image index. *--------------------------------------------------------------------------*/ SC CSPImageCache::ScMapScopeIndexToSnapinIndex ( SNAPINID sid, // I:what snap-in is this for? int nScopeIndex, // I:index by which the scope tree refers to the image int& nSnapinIndex) // O:index by which the snap-in refers to the image { DECLARE_SC (sc, _T("ScMapScopeIndexToSnapinIndex")); sc = E_FAIL; // assume failure /* * iterate through the map looking for scope indices matching the requested one */ for (POSITION pos = m_map.GetStartPosition(); pos != NULL; ) { SNAPINICONID key; DWORD value; m_map.GetNextAssoc (pos, key, value); /* * if this value matches the requested scope image index and it * belongs to the given snap-in, we've found a match; return it */ if ((value == nScopeIndex) && (GETSNAPINID(key) == sid)) { nSnapinIndex = GETICONID (key); sc = S_OK; break; } } return (sc); }