423 lines
9.4 KiB
C++
423 lines
9.4 KiB
C++
//____________________________________________________________________________
|
|
//
|
|
// 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<GUID, REFGUID>
|
|
{
|
|
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<WORD>(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<HICON>(pIcon), nLoc);
|
|
}
|
|
|
|
|
|
|
|
STDMETHODIMP
|
|
CSnapInImageList::ImageListSetStrip(
|
|
PLONG_PTR pBMapSm,
|
|
PLONG_PTR pBMapLg,
|
|
LONG nStartLoc,
|
|
COLORREF cMask)
|
|
{
|
|
BITMAP szSmall;
|
|
|
|
ASSERT(pBMapSm != NULL);
|
|
|
|
//HBITMAP hBMapSm = reinterpret_cast<HBITMAP>(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);
|
|
}
|