windows-nt/Source/XPSP1/NT/printscan/inc/psutil/comutils.h
2020-09-26 16:20:57 +08:00

335 lines
8.8 KiB
C++

/*****************************************************************************
*
* (C) COPYRIGHT MICROSOFT CORPORATION, 2000
*
* TITLE: comutils.h
*
* VERSION: 1.0
*
* AUTHOR: LazarI
*
* DATE: 23-Dec-2000
*
* DESCRIPTION: COM templates & utilities
*
*****************************************************************************/
#ifndef _COMUTILS_H
#define _COMUTILS_H
// the generic smart pointers & handles
#include "gensph.h"
////////////////////////////////////////////////
// template class CUnknownMT<pQITable>
//
// milti-thread impl. of IUnknown
// with interlocking for the ref-counting.
//
template <const QITAB* pQITable>
class CUnknownMT
{
public:
CUnknownMT(): m_cRefs(1) {}
virtual ~CUnknownMT() {}
//////////////////
// IUnknown
//
STDMETHODIMP Handle_QueryInterface(REFIID riid, void **ppv)
{
return QISearch(this, pQITable, riid, ppv);
}
STDMETHODIMP_(ULONG) Handle_AddRef()
{
return InterlockedIncrement(&m_cRefs);
}
STDMETHODIMP_(ULONG) Handle_Release()
{
ULONG cRefs = InterlockedDecrement(&m_cRefs);
if( 0 == cRefs )
{
delete this;
}
return cRefs;
}
private:
LONG m_cRefs;
};
////////////////////////////////////////////////
// template class CUnknownST<pQITable>
//
// single-thread impl. of IUnknown
// no interlocking for the ref-counting.
//
template <const QITAB* pQITable>
class CUnknownST
{
public:
CUnknownST(): m_cRefs(1) {}
virtual ~CUnknownST() {}
//////////////////
// IUnknown
//
STDMETHODIMP Handle_QueryInterface(REFIID riid, void **ppv)
{
return QISearch(this, pQITable, riid, ppv);
}
STDMETHODIMP_(ULONG) Handle_AddRef()
{
return m_cRefs++;
}
STDMETHODIMP_(ULONG) Handle_Release()
{
if( 0 == --m_cRefs )
{
delete this;
return 0;
}
return m_cRefs;
}
private:
LONG m_cRefs;
};
#define QITABLE_DECLARE(className) \
class className##_QITable \
{ \
public: \
static const QITAB qit[]; \
}; \
#define QITABLE_GET(className) \
className##_QITable::qit \
#define QITABLE_BEGIN(className) \
const QITAB className##_QITable::qit[] = \
{ \
#define QITABLE_END() \
{ 0 }, \
}; \
#define IMPLEMENT_IUNKNOWN() \
STDMETHODIMP QueryInterface(REFIID riid, void **ppv) \
{ return Handle_QueryInterface(riid, ppv); } \
STDMETHODIMP_(ULONG) AddRef() \
{ return Handle_AddRef(); } \
STDMETHODIMP_(ULONG) Release() \
{ return Handle_Release(); } \
#if FALSE
////////////////////////////////////////////////
// template class CEnumFormatEtc
//
// implementation for an IDataObject which
// supports SetData to different formats.
// - not implemented yet.
//
class CEnumFormatEtc: public IEnumFORMATETC
{
public:
CEnumFormatEtc(IUnknown *pUnkOuter, const FORMATETC *pfetc, UINT uSize);
~CEnumFormatEtc();
//////////////////
// IUnknown
//
STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
//////////////////
// IEnumFORMATETC
//
/* [local] */
virtual HRESULT STDMETHODCALLTYPE Next(
/* [in] */ ULONG celt,
/* [length_is][size_is][out] */ FORMATETC *rgelt,
/* [out] */ ULONG *pceltFetched) = 0;
virtual HRESULT STDMETHODCALLTYPE Skip(
/* [in] */ ULONG celt) = 0;
virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0;
virtual HRESULT STDMETHODCALLTYPE Clone(
/* [out] */ IEnumFORMATETC **ppenum) = 0;
private:
ULONG m_cRefs;
IUnknown *m_pUnkOuter;
LPFORMATETC m_prgfe;
ULONG m_iCur;
ULONG m_cItems;
};
#endif // #if FALSE
////////////////////////////////////////////////
// template class CDataObj<MAX_FORMATS>
//
// implementation for an IDataObject which
// supports SetData to different formats.
//
template <int MAX_FORMATS = 32>
class CDataObj: public IDataObject
{
public:
// construction/destruction
CDataObj();
~CDataObj();
//////////////////
// IUnknown
//
STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
//////////////////
// IDataObject
//
/* [local] */
virtual HRESULT STDMETHODCALLTYPE GetData(
/* [unique][in] */ FORMATETC *pformatetcIn,
/* [out] */ STGMEDIUM *pmedium);
/* [local] */
virtual HRESULT STDMETHODCALLTYPE GetDataHere(
/* [unique][in] */ FORMATETC *pformatetc,
/* [out][in] */ STGMEDIUM *pmedium);
virtual HRESULT STDMETHODCALLTYPE QueryGetData(
/* [unique][in] */ FORMATETC *pformatetc);
virtual HRESULT STDMETHODCALLTYPE GetCanonicalFormatEtc(
/* [unique][in] */ FORMATETC *pformatectIn,
/* [out] */ FORMATETC *pformatetcOut);
/* [local] */
virtual HRESULT STDMETHODCALLTYPE SetData(
/* [unique][in] */ FORMATETC *pformatetc,
/* [unique][in] */ STGMEDIUM *pmedium,
/* [in] */ BOOL fRelease);
virtual HRESULT STDMETHODCALLTYPE EnumFormatEtc(
/* [in] */ DWORD dwDirection,
/* [out] */ IEnumFORMATETC **ppenumFormatEtc);
virtual HRESULT STDMETHODCALLTYPE DAdvise(
/* [in] */ FORMATETC *pformatetc,
/* [in] */ DWORD advf,
/* [unique][in] */ IAdviseSink *pAdvSink,
/* [out] */ DWORD *pdwConnection);
virtual HRESULT STDMETHODCALLTYPE DUnadvise(
/* [in] */ DWORD dwConnection);
virtual HRESULT STDMETHODCALLTYPE EnumDAdvise(
/* [out] */ IEnumSTATDATA **ppenumAdvise);
private:
LONG m_cRefs;
FORMATETC m_fmte[MAX_FORMATS];
STGMEDIUM m_medium[MAX_FORMATS];
};
////////////////////////////////////////////////
// template class CSimpleDataObjImpl<T>
//
// simple implementation for an IDataObject
// and IDropSource which lives in memory.
//
template <class T>
class CSimpleDataObjImpl: public IDataObject,
public IDropSource
{
public:
// construction/destruction
CSimpleDataObjImpl(const T &data, CLIPFORMAT cfDataType, IDataObject *pDataObj = NULL);
~CSimpleDataObjImpl();
//////////////////
// IUnknown
//
STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
//////////////////
// IDataObject
//
/* [local] */
virtual HRESULT STDMETHODCALLTYPE GetData(
/* [unique][in] */ FORMATETC *pformatetcIn,
/* [out] */ STGMEDIUM *pmedium);
/* [local] */
virtual HRESULT STDMETHODCALLTYPE GetDataHere(
/* [unique][in] */ FORMATETC *pformatetc,
/* [out][in] */ STGMEDIUM *pmedium);
virtual HRESULT STDMETHODCALLTYPE QueryGetData(
/* [unique][in] */ FORMATETC *pformatetc);
virtual HRESULT STDMETHODCALLTYPE GetCanonicalFormatEtc(
/* [unique][in] */ FORMATETC *pformatectIn,
/* [out] */ FORMATETC *pformatetcOut);
/* [local] */
virtual HRESULT STDMETHODCALLTYPE SetData(
/* [unique][in] */ FORMATETC *pformatetc,
/* [unique][in] */ STGMEDIUM *pmedium,
/* [in] */ BOOL fRelease);
virtual HRESULT STDMETHODCALLTYPE EnumFormatEtc(
/* [in] */ DWORD dwDirection,
/* [out] */ IEnumFORMATETC **ppenumFormatEtc);
virtual HRESULT STDMETHODCALLTYPE DAdvise(
/* [in] */ FORMATETC *pformatetc,
/* [in] */ DWORD advf,
/* [unique][in] */ IAdviseSink *pAdvSink,
/* [out] */ DWORD *pdwConnection);
virtual HRESULT STDMETHODCALLTYPE DUnadvise(
/* [in] */ DWORD dwConnection);
virtual HRESULT STDMETHODCALLTYPE EnumDAdvise(
/* [out] */ IEnumSTATDATA **ppenumAdvise);
//////////////////
// IDropSource
//
virtual HRESULT STDMETHODCALLTYPE QueryContinueDrag(
/* [in] */ BOOL fEscapePressed,
/* [in] */ DWORD grfKeyState);
virtual HRESULT STDMETHODCALLTYPE GiveFeedback(
/* [in] */ DWORD dwEffect);
private:
LONG m_cRefs;
T m_data;
CLIPFORMAT m_cfDataType;
CRefPtrCOM<IDataObject> m_spDataObj;
};
// this namespace is a placeholder to put COM related helpers here
namespace comhelpers
{
BOOL AreObjectsIdentical(IUnknown *punk1, IUnknown *punk2);
}
// include the implementation of the template classes here
#include "comutils.inl"
#endif // endif _COMUTILS_H