335 lines
8.8 KiB
C
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
|
||
|
|