windows-nt/Source/XPSP1/NT/multimedia/dshow/h/comint.h
2020-09-26 16:20:57 +08:00

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__