240 lines
5.3 KiB
C
240 lines
5.3 KiB
C
|
// Copyright (c) 1995 - 1997 Microsoft Corporation. All Rights Reserved.
|
||
|
//
|
||
|
// comint.h
|
||
|
//
|
||
|
|
||
|
#ifndef __CCOMINT__
|
||
|
#define __CCOMINT__
|
||
|
|
||
|
#pragma warning( disable : 4290 ) // warning C4290: C++ Exception Specification ignored
|
||
|
|
||
|
|
||
|
// CCOMInt
|
||
|
//
|
||
|
// A class to manage COM interfaces - AddRef's in its constructor
|
||
|
// and releases in the destructor.
|
||
|
// It is intended to provide the same automatic releasing that CAutoLock
|
||
|
// provides for critical sections.
|
||
|
//
|
||
|
// Provides an overloaded dereferenceing operator for calling interface members.
|
||
|
//
|
||
|
// a typical use would be:
|
||
|
// CCOMInt<IMediaControl> IMC(IID_IMediaContol, punk);
|
||
|
//
|
||
|
// IMC->Run();
|
||
|
//
|
||
|
// I don't think this class is useful as a _complete_ replacement of
|
||
|
// interface pointers, for two reasons:
|
||
|
// - using heap allocated objects (if you want a lifetime longer than the scope)
|
||
|
// has some ugly syntax:
|
||
|
// CCOMInt<IPersist> *pIPer = new CCOMInt<IPersist>(IID_IPersist, pSomeInt);
|
||
|
//
|
||
|
// (*pIPer)->GetClassID() // YUK!
|
||
|
//
|
||
|
// In this context I'm not sure how useful the CoCreate'ing constructor is...
|
||
|
//
|
||
|
// - constructing these objects from functions that give you addref'd interfcaces
|
||
|
// is inconvienent
|
||
|
//
|
||
|
// IStream *pStrm;
|
||
|
// hr = pStorage->CreateStream(, , , &pStrm);
|
||
|
// if (FAILED(hr)) {
|
||
|
// // do something appropriate
|
||
|
// }
|
||
|
// CCOMInt<IStream> IStrm(pStrm);
|
||
|
// pStrm->Release();
|
||
|
//
|
||
|
// [...use IStrm...]
|
||
|
//
|
||
|
//
|
||
|
// If you want to use this you need to add the following to you compiler
|
||
|
// options:
|
||
|
//
|
||
|
// you must #define: _INC_EXCPT
|
||
|
// and add the switch: -GX
|
||
|
//
|
||
|
// NB: this file uses the exception classes defined in hrExcept.h
|
||
|
|
||
|
|
||
|
//
|
||
|
// CCOMInt
|
||
|
//
|
||
|
template<class I>
|
||
|
class CCOMInt {
|
||
|
public:
|
||
|
|
||
|
// -- Constructors --
|
||
|
|
||
|
// CoCreate
|
||
|
CCOMInt<I>( REFIID riid // get this interface
|
||
|
, REFCLSID rclsid // get the interface
|
||
|
// from this object
|
||
|
, LPUNKNOWN pUnkOuter = NULL // controlling unknown
|
||
|
, DWORD dwClsContext = CLSCTX_INPROC_SERVER // CoCreate options
|
||
|
// default is suitable
|
||
|
// for dll servers
|
||
|
)
|
||
|
throw (CHRESULTException) {
|
||
|
#ifdef NOCOMLITE
|
||
|
HRESULT hr = CoCreateInstance( rclsid
|
||
|
, pUnkOuter
|
||
|
, dwClsContext
|
||
|
, riid
|
||
|
, (void **) &m_pInt
|
||
|
);
|
||
|
#else
|
||
|
HRESULT hr = QzCreateFilterObject( rclsid
|
||
|
, pUnkOuter
|
||
|
, dwClsContext
|
||
|
, riid
|
||
|
, (void **) &m_pInt
|
||
|
);
|
||
|
#endif
|
||
|
if (FAILED(hr)) {
|
||
|
throw CHRESULTException(hr);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// QueryInterface
|
||
|
CCOMInt<I>( REFIID riid // get this interface
|
||
|
, IUnknown *punk // from this interface
|
||
|
)
|
||
|
throw (CHRESULTException) {
|
||
|
|
||
|
HRESULT hr = punk->QueryInterface(riid, (void **) &m_pInt);
|
||
|
if (FAILED(hr)) {
|
||
|
throw CHRESULTException(hr);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// copy
|
||
|
CCOMInt<I>(const CCOMInt<I> &com)
|
||
|
throw () {
|
||
|
|
||
|
// #ifdef USE_MSVC20
|
||
|
m_pInt = com;
|
||
|
// #else
|
||
|
// m_pInt = const_cast<I*>(com); // new ANSI C++ in VC40
|
||
|
// #endif
|
||
|
(*this)->AddRef();
|
||
|
}
|
||
|
|
||
|
// existing pointer.
|
||
|
CCOMInt<I>(I *pInt)
|
||
|
throw (CHRESULTException) {
|
||
|
if (pInt == NULL) {
|
||
|
throw CHRESULTException(E_NOINTERFACE);
|
||
|
}
|
||
|
|
||
|
m_pInt = pInt;
|
||
|
|
||
|
(*this)->AddRef();
|
||
|
}
|
||
|
|
||
|
|
||
|
// assignment operator
|
||
|
CCOMInt<I>& operator = (const CCOMInt<I> &com)
|
||
|
throw () {
|
||
|
|
||
|
if (this != &com) { // not i = i
|
||
|
|
||
|
(*this)->Release();
|
||
|
// #ifdef USE_MSVC20
|
||
|
m_pInt = com;
|
||
|
// #else
|
||
|
// m_pInt = const_cast<I*>(com); // new ANSI C++ in VC40
|
||
|
// #endif
|
||
|
(*this)->AddRef();
|
||
|
}
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
|
||
|
// destructor
|
||
|
~CCOMInt<I>()
|
||
|
throw () {
|
||
|
m_pInt->Release();
|
||
|
}
|
||
|
|
||
|
|
||
|
// -- comparison operators --
|
||
|
BOOL operator == (IUnknown *punk)
|
||
|
|
||
|
#ifdef USE_MSVC20
|
||
|
throw(CHRESULTException) const
|
||
|
#else
|
||
|
const throw (CHRESULTException)
|
||
|
#endif
|
||
|
{
|
||
|
CCOMInt<IUnknown> IUnk1(IID_IUnknown, punk);
|
||
|
CCOMInt<IUnknown> IUnk2(IID_IUnknown, *this);
|
||
|
|
||
|
return ( ((IUnknown *)IUnk1) == ((IUnknown *)IUnk2) );
|
||
|
}
|
||
|
|
||
|
BOOL operator != (IUnknown *punk)
|
||
|
#ifdef USE_MSVC20
|
||
|
throw(CHRESULTException) const
|
||
|
#else
|
||
|
const throw (CHRESULTException)
|
||
|
#endif
|
||
|
{
|
||
|
return !(*this == punk);
|
||
|
}
|
||
|
|
||
|
|
||
|
// cast to interface pointer
|
||
|
operator I *()
|
||
|
#ifdef USE_MSVC20
|
||
|
throw() const
|
||
|
#else
|
||
|
const throw ()
|
||
|
#endif
|
||
|
{
|
||
|
return m_pInt;
|
||
|
}
|
||
|
|
||
|
|
||
|
// dereference
|
||
|
I *operator->()
|
||
|
#ifdef USE_MSVC20
|
||
|
throw() const
|
||
|
#else
|
||
|
const throw ()
|
||
|
#endif
|
||
|
{
|
||
|
return m_pInt;
|
||
|
}
|
||
|
|
||
|
I &operator*()
|
||
|
#ifdef USE_MSVC20
|
||
|
throw() const
|
||
|
#else
|
||
|
const throw ()
|
||
|
#endif
|
||
|
{
|
||
|
return *m_pInt;
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
|
||
|
I *m_pInt;
|
||
|
|
||
|
// array dereferencing seems to make no sense.
|
||
|
I &operator[] (int i)
|
||
|
|
||
|
#ifdef USE_MSVC20
|
||
|
throw(CHRESULTException) const
|
||
|
#else
|
||
|
const throw (CHRESULTException)
|
||
|
#endif
|
||
|
{
|
||
|
throw CHRESULTException();
|
||
|
return *m_pInt;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|
||
|
#endif // __CCOMINT__
|