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

//____________________________________________________________________________
//
// 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);
}