windows-nt/Source/XPSP1/NT/public/sdk/inc/mfc42/afxcom_.h
2020-09-26 16:20:57 +08:00

481 lines
12 KiB
C++

// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1998 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
/////////////////////////////////////////////////////////////////////////////
// AFXCOM_.H
//
// THIS FILE IS FOR MFC IMPLEMENTATION ONLY.
#ifndef __AFXCOM_H__
#define __AFXCOM_H__
#ifndef _OBJBASE_H_
#include <objbase.h>
#endif
/////////////////////////////////////////////////////////////////////////////
#ifdef _AFX_MINREBUILD
#pragma component(minrebuild, off)
#endif
#ifndef _AFX_FULLTYPEINFO
#pragma component(mintypeinfo, on)
#endif
/////////////////////////////////////////////////////////////////////////////
#ifndef _AFX_NOFORCE_LIBS
#pragma comment(lib, "uuid.lib")
#endif
/////////////////////////////////////////////////////////////////////////////
#ifdef _AFX_PACKING
#pragma pack(push, _AFX_PACKING)
#endif
#ifndef ASSERT
#ifndef _INC_CRTDBG
#include <crtdbg.h>
#endif // _INC_CRTDBG
#define ASSERT(x) _ASSERT(x)
#endif // ASSERT
/////////////////////////////////////////////////////////////////////////////
template<class _Interface, const IID* _IID>
class _CIP
{
public:
// Declare interface type so that the type may be available outside
// the scope of this template.
typedef _Interface Interface;
// When the compiler supports references in template params,
// _CLSID will be changed to a reference. To avoid conversion
// difficulties this function should be used to obtain the
// CLSID.
static const IID& GetIID()
{ ASSERT(_IID != NULL); return *_IID; }
// Construct empty in preperation for assignment.
_CIP();
// Copy the pointer and AddRef().
_CIP(const _CIP& cp) : _pInterface(cp._pInterface)
{ _AddRef(); }
// Saves and AddRef()'s the interface
_CIP(Interface* pInterface) : _pInterface(pInterface)
{ _AddRef(); }
// Copies the pointer. If bAddRef is TRUE, the interface will
// be AddRef()ed.
_CIP(Interface* pInterface, BOOL bAddRef)
: _pInterface(pInterface)
{
if (bAddRef)
{
ASSERT(pInterface != NULL);
_AddRef();
}
}
// Calls CoCreateClass with the provided CLSID.
_CIP(const CLSID& clsid, DWORD dwClsContext = CLSCTX_INPROC_SERVER)
: _pInterface(NULL)
{
CreateObject(clsid, dwClsContext);
}
// Calls CoCreateClass with the provided CLSID retrieved from
// the string.
_CIP(LPOLESTR str, DWORD dwClsContext = CLSCTX_INPROC_SERVER)
: _pInterface(NULL)
{
CreateObject(str, dwClsContext);
}
// Saves and AddRef()s the interface.
_CIP& operator=(Interface* pInterface)
{
if (_pInterface != pInterface)
{
Interface* pOldInterface = _pInterface;
_pInterface = pInterface;
_AddRef();
if (pOldInterface != NULL)
pOldInterface->Release();
}
return *this;
}
// Copies and AddRef()'s the interface.
_CIP& operator=(const _CIP& cp)
{ return operator=(cp._pInterface); }
// Releases any current interface and loads the class with the
// provided CLSID.
_CIP& operator=(const CLSID& clsid)
{
CreateObject(clsid);
return *this;
}
// Calls CoCreateClass with the provided CLSID retrieved from
// the string.
_CIP& operator=(LPOLESTR str)
{
CreateObject(str);
return *this;
}
~_CIP();
// Saves/sets the interface without AddRef()ing. This call
// will release any previously aquired interface.
void Attach(Interface* pInterface)
{
_Release();
_pInterface = pInterface;
}
// Saves/sets the interface only AddRef()ing if bAddRef is TRUE.
// This call will release any previously aquired interface.
void Attach(Interface* pInterface, BOOL bAddRef)
{
_Release();
_pInterface = pInterface;
if (bAddRef)
{
ASSERT(pInterface != NULL);
pInterface->AddRef();
}
}
// Simply NULL the interface pointer so that it isn't Released()'ed.
void Detach()
{
ASSERT(_pInterface);
_pInterface = NULL;
}
// Return the interface. This value may be NULL
operator Interface*() const
{ return _pInterface; }
// Queries for the unknown and return it
operator IUnknown*()
{ return _pInterface; }
// Provides minimal level assertion before use.
operator Interface&() const
{ ASSERT(_pInterface); return *_pInterface; }
// Allows an instance of this class to act as though it were the
// actual interface. Also provides minimal assertion verification.
Interface& operator*() const
{ ASSERT(_pInterface); return *_pInterface; }
// Returns the address of the interface pointer contained in this
// class. This is useful when using the COM/OLE interfaces to create
// this interface.
Interface** operator&()
{
_Release();
_pInterface = NULL;
return &_pInterface;
}
// Allows this class to be used as the interface itself.
// Also provides simple assertion verification.
Interface* operator->() const
{ ASSERT(_pInterface != NULL); return _pInterface; }
// This operator is provided so that simple boolean expressions will
// work. For example: "if (p) ...".
// Returns TRUE if the pointer is not NULL.
operator BOOL() const
{ return _pInterface != NULL; }
// Returns TRUE if the interface is NULL.
// This operator will be removed when support for type bool
// is added to the compiler.
BOOL operator!()
{ return _pInterface == NULL; }
// Provides assertion verified, Release()ing of this interface.
void Release()
{
ASSERT(_pInterface != NULL);
_pInterface->Release();
_pInterface = NULL;
}
// Provides assertion verified AddRef()ing of this interface.
void AddRef()
{ ASSERT(_pInterface != NULL); _pInterface->AddRef(); }
// Another way to get the interface pointer without casting.
Interface* GetInterfacePtr() const
{ return _pInterface; }
// Loads an interface for the provided CLSID.
// Returns an HRESULT. Any previous interface is released.
HRESULT CreateObject(
const CLSID& clsid, DWORD dwClsContext=CLSCTX_INPROC_SERVER)
{
_Release();
HRESULT hr = CoCreateInstance(clsid, NULL, dwClsContext,
GetIID(), reinterpret_cast<void**>(&_pInterface));
ASSERT(SUCCEEDED(hr));
return hr;
}
// Creates the class specified by clsidString. clsidString may
// contain a class id, or a prog id string.
HRESULT CreateObject(
LPOLESTR clsidString, DWORD dwClsContext=CLSCTX_INPROC_SERVER)
{
ASSERT(clsidString != NULL);
CLSID clsid;
HRESULT hr;
if (clsidString[0] == '{')
hr = CLSIDFromString(clsidString, &clsid);
else
hr = CLSIDFromProgID(clsidString, &clsid);
ASSERT(SUCCEEDED(hr));
if (FAILED(hr))
return hr;
return CreateObject(clsid, dwClsContext);
}
// Performs a QI on pUnknown for the interface type returned
// for this class. The interface is stored. If pUnknown is
// NULL, or the QI fails, E_NOINTERFACE is returned and
// _pInterface is set to NULL.
HRESULT QueryInterface(IUnknown* pUnknown)
{
if (pUnknown == NULL) // Can't QI NULL
{
operator=(static_cast<Interface*>(NULL));
return E_NOINTERFACE;
}
// Query for this interface
Interface* pInterface;
HRESULT hr = pUnknown->QueryInterface(GetIID(),
reinterpret_cast<void**>(&pInterface));
if (FAILED(hr))
{
// If failed intialize interface to NULL and return HRESULT.
Attach(NULL);
return hr;
}
// Save the interface without AddRef()ing.
Attach(pInterface);
return hr;
}
private:
// Releases only if the interface is not null.
// The interface is not set to NULL.
void _Release()
{
if (_pInterface != NULL)
_pInterface->Release();
}
// AddRefs only if the interface is not NULL
void _AddRef()
{
if (_pInterface != NULL)
_pInterface->AddRef();
}
// The Interface.
Interface* _pInterface;
}; // class _CIP
template<class _Interface, const IID* _IID>
_CIP<_Interface, _IID>::_CIP<_Interface, _IID>()
: _pInterface(NULL)
{
}
template<class _Interface, const IID* _IID>
_CIP<_Interface, _IID>::~_CIP<_Interface, _IID>()
{
// If we still have an interface then Release() it. The interface
// may be NULL if Detach() has previosly been called, or if it was
// never set.
_Release();
}
template<class _Interface, const IID* _IID>
class CIP : public _CIP<_Interface, _IID>
{
public:
// Simplified name for base class and provide derived classes
// access to base type
typedef _CIP<_Interface, _IID> BC;
// Provideds derived classes access to the interface type.
typedef _Interface Interface;
// Construct empty in preperation for assignment.
CIP() { }
~CIP();
// Copy the pointer and AddRef().
CIP(const CIP& cp) : _CIP<_Interface, _IID>(cp) { }
// Saves and AddRef()s the interface.
CIP(Interface* pInterface) : _CIP<_Interface, _IID>(pInterface) { }
// Saves the interface and AddRef()s only if bAddRef is TRUE.
CIP(Interface* pInterface, BOOL bAddRef)
: _CIP<_Interface, _IID>(pInterface, bAddRef) { }
// Queries for this interface.
CIP(IUnknown* pUnknown)
{
if (pUnknown == NULL)
return;
Interface* pInterface;
HRESULT hr = pUnknown->QueryInterface(GetIID(),
reinterpret_cast<void**>(&pInterface));
ASSERT(SUCCEEDED(hr));
Attach(pInterface);
}
// Creates the interface from the CLSID.
CIP(const CLSID& clsid) : _CIP<_Interface, _IID>(clsid) { }
// Creates the interface from the CLSID.
CIP(LPOLESTR str) : _CIP<_Interface, _IID>(str) { }
// Copies and AddRef()'s the interface.
CIP& operator=(const CIP& cp)
{ _CIP<_Interface, _IID>::operator=(cp); return *this; }
// Saves and AddRef()s the interface.
CIP& operator=(Interface* pInterface)
{ _CIP<_Interface, _IID>::operator=(pInterface); return *this; }
CIP& operator=(IUnknown* pUnknown)
{
HRESULT hr = QueryInterface(pUnknown);
ASSERT(SUCCEEDED(hr));
return *this;
}
// Releases any current interface and loads the class with the
// provided CLSID.
CIP& operator=(const CLSID& clsid)
{ _CIP<_Interface, _IID>::operator=(clsid); return *this; }
// Releases any current interface and loads the class with the
// provided CLSID.
CIP& operator=(LPOLESTR str)
{ _CIP<_Interface, _IID>::operator=(str); return *this; }
}; // class CIP
template<class _Interface, const IID* _IID>
CIP<_Interface, _IID>::~CIP()
{
}
#if _MSC_VER>1020
template<>
#endif
class CIP<IUnknown, &IID_IUnknown> : public _CIP<IUnknown, &IID_IUnknown>
{
public:
// Simplified name for base class and provide derived classes
// access to base type
typedef _CIP<IUnknown, &IID_IUnknown> BC;
// Provideds derived classes access to the interface type.
typedef IUnknown Interface;
// Construct empty in preperation for assignment.
CIP() { }
// Copy the pointer and AddRef().
CIP(const CIP& cp) : _CIP<IUnknown, &IID_IUnknown>(cp) { }
// Saves and AddRef()s the interface.
CIP(Interface* pInterface)
: _CIP<IUnknown, &IID_IUnknown>(pInterface) { }
// Saves and then AddRef()s only if bAddRef is TRUE.
CIP(Interface* pInterface, BOOL bAddRef)
: _CIP<IUnknown, &IID_IUnknown>(pInterface, bAddRef) { }
// Creates the interface from the CLSID.
CIP(const CLSID& clsid) : _CIP<IUnknown, &IID_IUnknown>(clsid) { }
// Creates the interface from the CLSID.
CIP(LPOLESTR str) : _CIP<IUnknown, &IID_IUnknown>(str) { }
// Copies and AddRef()'s the interface.
CIP& operator=(const CIP& cp)
{ _CIP<IUnknown, &IID_IUnknown>::operator=(cp); return *this; }
// Saves and AddRef()s the interface. The previously saved
// interface is released.
CIP& operator=(Interface* pInterface)
{ _CIP<IUnknown, &IID_IUnknown>::operator=(pInterface); return *this; }
// Releases any current interface and loads the class with the
// provided CLSID.
CIP& operator=(const CLSID& clsid)
{ _CIP<IUnknown, &IID_IUnknown>::operator=(clsid); return *this; }
// Releases any current interface and loads the class with the
// provided CLSID.
CIP& operator=(LPOLESTR str)
{ _CIP<IUnknown, &IID_IUnknown>::operator=(str); return *this; }
// Queries for the unknown and return it
operator IUnknown*()
{ return GetInterfacePtr(); }
// Verifies that pUnknown is not null and performs assignment.
HRESULT QueryInterface(IUnknown* pUnknown)
{
_CIP<IUnknown, &IID_IUnknown>::operator=(pUnknown);
return pUnknown != NULL ? S_OK : E_NOINTERFACE;
}
}; // CIP<IUnknown, &IID_IUnknown>
#define IPTR(x) CIP<x, &IID_##x>
#define DEFINE_IPTR(x) typedef IPTR(x) x##Ptr;
/////////////////////////////////////////////////////////////////////////////
#ifdef _AFX_PACKING
#pragma pack(pop)
#endif
#ifdef _AFX_MINREBUILD
#pragma component(minrebuild, on)
#endif
#ifndef _AFX_FULLTYPEINFO
#pragma component(mintypeinfo, off)
#endif
#endif // __AFXCOM_H__
/////////////////////////////////////////////////////////////////////////////