home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tricks of the Windows Gam…ming Gurus (2nd Edition)
/
Disc2.iso
/
msdn_vcb
/
samples
/
vc98
/
com
/
acdual
/
server
/
mfcdual.h
< prev
next >
Wrap
Text File
|
1998-04-02
|
7KB
|
170 lines
// mfcdual.h: Helpful macros for adding dual interface support to
// MFC applications
// 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.
/////////////////////////////////////////////////////////////////////
// BEGIN_DUAL_INTERFACE_PART is just like BEGIN_INTERFACE_PART,
// except that it also adds the IDispatch methods to your class
// declaration.
#define BEGIN_DUAL_INTERFACE_PART(localClass, baseClass) \
BEGIN_INTERFACE_PART(localClass, baseClass) \
STDMETHOD(GetTypeInfoCount)(UINT FAR* pctinfo); \
STDMETHOD(GetTypeInfo)(UINT itinfo, LCID lcid, ITypeInfo FAR* FAR* pptinfo); \
STDMETHOD(GetIDsOfNames)(REFIID riid, OLECHAR FAR* FAR* rgszNames, UINT cNames, LCID lcid, DISPID FAR* rgdispid); \
STDMETHOD(Invoke)(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR* pdispparams, VARIANT FAR* pvarResult, EXCEPINFO FAR* pexcepinfo, UINT FAR* puArgErr); \
/////////////////////////////////////////////////////////////////////
// END_DUAL_INTERFACE_PART is just like END_INTERFACE_PART. It
// is only added for symmetry...
#define END_DUAL_INTERFACE_PART(localClass) \
END_INTERFACE_PART(localClass) \
/////////////////////////////////////////////////////////////////////
// DELEGATE_DUAL_INTERFACE expands to define the standard IDispatch
// methods for a dual interface, delegating back to the default
// MFC implementation
#define DELEGATE_DUAL_INTERFACE(objectClass, dualClass) \
STDMETHODIMP_(ULONG) objectClass::X##dualClass::AddRef() \
{ \
METHOD_PROLOGUE(objectClass, dualClass) \
return pThis->ExternalAddRef(); \
} \
STDMETHODIMP_(ULONG) objectClass::X##dualClass::Release() \
{ \
METHOD_PROLOGUE(objectClass, dualClass) \
return pThis->ExternalRelease(); \
} \
STDMETHODIMP objectClass::X##dualClass::QueryInterface( \
REFIID iid, LPVOID* ppvObj) \
{ \
METHOD_PROLOGUE(objectClass, dualClass) \
return pThis->ExternalQueryInterface(&iid, ppvObj); \
} \
STDMETHODIMP objectClass::X##dualClass::GetTypeInfoCount( \
UINT FAR* pctinfo) \
{ \
METHOD_PROLOGUE(objectClass, dualClass) \
LPDISPATCH lpDispatch = pThis->GetIDispatch(FALSE); \
ASSERT(lpDispatch != NULL); \
return lpDispatch->GetTypeInfoCount(pctinfo); \
} \
STDMETHODIMP objectClass::X##dualClass::GetTypeInfo( \
UINT itinfo, LCID lcid, ITypeInfo FAR* FAR* pptinfo) \
{ \
METHOD_PROLOGUE(objectClass, dualClass) \
LPDISPATCH lpDispatch = pThis->GetIDispatch(FALSE); \
ASSERT(lpDispatch != NULL); \
return lpDispatch->GetTypeInfo(itinfo, lcid, pptinfo); \
} \
STDMETHODIMP objectClass::X##dualClass::GetIDsOfNames( \
REFIID riid, OLECHAR FAR* FAR* rgszNames, UINT cNames, \
LCID lcid, DISPID FAR* rgdispid) \
{ \
METHOD_PROLOGUE(objectClass, dualClass) \
LPDISPATCH lpDispatch = pThis->GetIDispatch(FALSE); \
ASSERT(lpDispatch != NULL); \
return lpDispatch->GetIDsOfNames(riid, rgszNames, cNames, \
lcid, rgdispid); \
} \
STDMETHODIMP objectClass::X##dualClass::Invoke( \
DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, \
DISPPARAMS FAR* pdispparams, VARIANT FAR* pvarResult, \
EXCEPINFO FAR* pexcepinfo, UINT FAR* puArgErr) \
{ \
METHOD_PROLOGUE(objectClass, dualClass) \
LPDISPATCH lpDispatch = pThis->GetIDispatch(FALSE); \
ASSERT(lpDispatch != NULL); \
return lpDispatch->Invoke(dispidMember, riid, lcid, \
wFlags, pdispparams, pvarResult, \
pexcepinfo, puArgErr); \
} \
/////////////////////////////////////////////////////////////////////
// TRY_DUAL and CATCH_ALL_DUAL are used to provide exception handling
// for your dual interface methods. CATCH_ALL_DUAL takes care of
// returning the appropriate error code.
#define TRY_DUAL(iidSource) \
HRESULT _hr = S_OK; \
REFIID _riidSource = iidSource; \
TRY \
#define CATCH_ALL_DUAL \
CATCH(COleException, e) \
{ \
_hr = e->m_sc; \
} \
AND_CATCH_ALL(e) \
{ \
AFX_MANAGE_STATE(pThis->m_pModuleState); \
_hr = DualHandleException(_riidSource, e); \
} \
END_CATCH_ALL \
return _hr; \
/////////////////////////////////////////////////////////////////////
// DualHandleException is a helper function used to set the system's
// error object, so that container applications that call through
// VTBLs can retrieve rich error information
HRESULT DualHandleException(REFIID riidSource, const CException* pAnyException);
/////////////////////////////////////////////////////////////////////
// DECLARE_DUAL_ERRORINFO expands to declare the ISupportErrorInfo
// support class. It works together with DUAL_ERRORINFO_PART and
// IMPLEMENT_DUAL_ERRORINFO defined below.
#define DECLARE_DUAL_ERRORINFO() \
BEGIN_INTERFACE_PART(SupportErrorInfo, ISupportErrorInfo) \
STDMETHOD(InterfaceSupportsErrorInfo)(THIS_ REFIID riid); \
END_INTERFACE_PART(SupportErrorInfo) \
/////////////////////////////////////////////////////////////////////
// DUAL_ERRORINFO_PART adds the appropriate entry to the interface map
// for ISupportErrorInfo, if you used DECLARE_DUAL_ERRORINFO.
#define DUAL_ERRORINFO_PART(objectClass) \
INTERFACE_PART(objectClass, IID_ISupportErrorInfo, SupportErrorInfo) \
/////////////////////////////////////////////////////////////////////
// IMPLEMENT_DUAL_ERRORINFO expands to an implementation of
// ISupportErrorInfo which matches the declaration in
// DECLARE_DUAL_ERRORINFO.
#define IMPLEMENT_DUAL_ERRORINFO(objectClass, riidSource) \
STDMETHODIMP_(ULONG) objectClass::XSupportErrorInfo::AddRef() \
{ \
METHOD_PROLOGUE(objectClass, SupportErrorInfo) \
return pThis->ExternalAddRef(); \
} \
STDMETHODIMP_(ULONG) objectClass::XSupportErrorInfo::Release() \
{ \
METHOD_PROLOGUE(objectClass, SupportErrorInfo) \
return pThis->ExternalRelease(); \
} \
STDMETHODIMP objectClass::XSupportErrorInfo::QueryInterface( \
REFIID iid, LPVOID* ppvObj) \
{ \
METHOD_PROLOGUE(objectClass, SupportErrorInfo) \
return pThis->ExternalQueryInterface(&iid, ppvObj); \
} \
STDMETHODIMP objectClass::XSupportErrorInfo::InterfaceSupportsErrorInfo( \
REFIID iid) \
{ \
METHOD_PROLOGUE(objectClass, SupportErrorInfo) \
return (iid == riidSource) ? S_OK : S_FALSE; \
}
/////////////////////////////////////////////////////////////////////