You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
391 lines
19 KiB
391 lines
19 KiB
//____________________________________________________________________________
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1995 - 1996.
|
|
//
|
|
// File: macros.h
|
|
//
|
|
// Contents: Useful macros
|
|
//
|
|
// Macros: ARRAYLEN
|
|
//
|
|
// BREAK_ON_FAIL(hresult)
|
|
// BREAK_ON_FAIL(hresult)
|
|
//
|
|
// DECLARE_IUNKNOWN_METHODS
|
|
// DECLARE_STANDARD_IUNKNOWN
|
|
// IMPLEMENT_STANDARD_IUNKNOWN
|
|
//
|
|
// SAFE_RELEASE
|
|
//
|
|
// DECLARE_SAFE_INTERFACE_PTR_MEMBERS
|
|
//
|
|
// History: 6/3/1996 RaviR Created
|
|
// 7/23/1996 JonN Added exception handling macros
|
|
//
|
|
//____________________________________________________________________________
|
|
|
|
#ifndef _MACROS_H_
|
|
#define _MACROS_H_
|
|
|
|
|
|
//____________________________________________________________________________
|
|
//
|
|
// Macro: ARRAYLEN
|
|
//
|
|
// Purpose: To determine the length of an array.
|
|
//____________________________________________________________________________
|
|
//
|
|
|
|
#define ARRAYLEN(a) (sizeof(a) / sizeof((a)[0]))
|
|
|
|
|
|
//____________________________________________________________________________
|
|
//
|
|
// Macros: BREAK_ON_FAIL(hresult), BREAK_ON_ERROR(lastError)
|
|
//
|
|
// Purpose: To break out of a loop on error.
|
|
//____________________________________________________________________________
|
|
//
|
|
|
|
#define BREAK_ON_FAIL(hr) if (FAILED(hr)) { break; } else 1;
|
|
|
|
#define BREAK_ON_ERROR(lr) if (lr != ERROR_SUCCESS) { break; } else 1;
|
|
|
|
|
|
//____________________________________________________________________________
|
|
//
|
|
// Macros: DwordAlign(n)
|
|
//____________________________________________________________________________
|
|
//
|
|
|
|
#define DwordAlign(n) (((n) + 3) & ~3)
|
|
|
|
|
|
//____________________________________________________________________________
|
|
//
|
|
// Macros: SAFE_RELEASE
|
|
//____________________________________________________________________________
|
|
//
|
|
|
|
#ifndef SAFE_RELEASE
|
|
#define SAFE_RELEASE(punk) \
|
|
if (punk != NULL) \
|
|
{ \
|
|
punk##->Release(); \
|
|
punk = NULL; \
|
|
} \
|
|
else \
|
|
{ \
|
|
TRACE(_T("Release called on NULL interface ptr")); \
|
|
}
|
|
#endif // SAFE_RELEASE
|
|
|
|
|
|
|
|
//____________________________________________________________________________
|
|
//
|
|
// Macro: DECLARE_IUNKNOWN_METHODS
|
|
//
|
|
// Purpose: This declares the set of IUnknown methods and is for
|
|
// general-purpose use inside classes that inherit from IUnknown
|
|
//____________________________________________________________________________
|
|
//
|
|
|
|
#define DECLARE_IUNKNOWN_METHODS \
|
|
STDMETHOD(QueryInterface) (REFIID riid, LPVOID FAR* ppvObj); \
|
|
STDMETHOD_(ULONG,AddRef) (void); \
|
|
STDMETHOD_(ULONG,Release) (void)
|
|
|
|
//____________________________________________________________________________
|
|
//
|
|
// Macro: DECLARE_STANDARD_IUNKNOWN
|
|
//
|
|
// Purpose: This is for use in declaring non-aggregatable objects. It
|
|
// declares the IUnknown methods and reference counter, m_ulRefs.
|
|
// m_ulRefs should be initialized to 1 in the constructor of
|
|
// the object
|
|
//____________________________________________________________________________
|
|
//
|
|
|
|
#define DECLARE_STANDARD_IUNKNOWN \
|
|
DECLARE_IUNKNOWN_METHODS; \
|
|
ULONG m_ulRefs
|
|
|
|
|
|
//____________________________________________________________________________
|
|
//
|
|
// Macro: IMPLEMENT_STANDARD_IUNKNOWN
|
|
//
|
|
// Purpose: Partial implementaion of standard IUnknown.
|
|
//
|
|
// Note: This does NOT implement QueryInterface, which must be
|
|
// implemented by each object
|
|
//____________________________________________________________________________
|
|
//
|
|
|
|
#define IMPLEMENT_STANDARD_IUNKNOWN(cls) \
|
|
STDMETHODIMP_(ULONG) cls##::AddRef() \
|
|
{ return InterlockedIncrement((LONG*)&m_ulRefs); } \
|
|
STDMETHODIMP_(ULONG) cls##::Release() \
|
|
{ ULONG ulRet = InterlockedDecrement((LONG*)&m_ulRefs); \
|
|
if (0 == ulRet) { delete this; } \
|
|
return ulRet; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ISSUE-2002/04/01-JonN This is not used, remove it
|
|
|
|
//____________________________________________________________________________
|
|
//
|
|
// Macro: DECLARE_SAFE_INTERFACE_PTR_MEMBERS(cls, Interface, m_iptr)
|
|
//
|
|
// Purpose: Make the interface ptr 'm_iptr' of interface type 'Interface'
|
|
// a safe pointer for the given class 'cls', by adding methods and
|
|
// overloading operators to manipulate the pointer m_iptr.
|
|
//
|
|
// History: 6/3/1996 RaviR Created
|
|
//
|
|
// Notes: Adds safe interface pointer member functions to the given
|
|
// class for the given OLE interface. 'm_iptr' is the member
|
|
// variable name of the interface ptr in the given class.
|
|
//
|
|
// The Copy function creates a valid additional copy of
|
|
// the captured pointer (following the AddRef/Release protocol)
|
|
// so can be used to hand out copies from a safe pointer declared
|
|
// as a member of some other class.
|
|
//
|
|
// The 'Transfer' function transfers the interface pointer, and
|
|
// invalidates its member value (by setting it to NULL).
|
|
//
|
|
// To release the existing interface ptr and set it to a new
|
|
// instance use the 'Set' member fuction. This method takes a
|
|
// parameter which specifies whether the new pointer should be
|
|
// AddRef'd, defaulting to TRUE.
|
|
//
|
|
// The following methods manipulate the interface pointer with
|
|
// out following the AddRef/Release protocol: Transfer, Attach
|
|
// and Detach.
|
|
//____________________________________________________________________________
|
|
//
|
|
|
|
#define DECLARE_SAFE_INTERFACE_PTR_MEMBERS(cls, Interface, m_iptr) \
|
|
\
|
|
public: \
|
|
cls##(Interface * iptr=NULL, BOOL fInc=TRUE) : m_iptr(iptr) \
|
|
{ \
|
|
if (fInc && (m_iptr != NULL)) \
|
|
{ \
|
|
m_iptr->AddRef(); \
|
|
} \
|
|
} \
|
|
\
|
|
~##cls##() \
|
|
{ \
|
|
if (m_iptr != NULL) \
|
|
{ \
|
|
m_iptr->Release(); \
|
|
m_iptr = NULL; \
|
|
} \
|
|
} \
|
|
\
|
|
inline BOOL IsNull(void) \
|
|
{ \
|
|
return (m_iptr == NULL); \
|
|
} \
|
|
\
|
|
void Transfer(Interface **piptr) \
|
|
{ \
|
|
*piptr = m_iptr; \
|
|
m_iptr = NULL; \
|
|
} \
|
|
\
|
|
void Copy(Interface **piptr) \
|
|
{ \
|
|
*piptr = m_iptr; \
|
|
if (m_iptr != NULL) \
|
|
m_iptr->AddRef(); \
|
|
} \
|
|
\
|
|
void Set(Interface* iptr, BOOL fInc = TRUE) \
|
|
{ \
|
|
if (m_iptr) \
|
|
{ \
|
|
m_iptr->Release(); \
|
|
} \
|
|
m_iptr = iptr; \
|
|
if (fInc && m_iptr) \
|
|
{ \
|
|
m_iptr->AddRef(); \
|
|
} \
|
|
} \
|
|
\
|
|
void SafeRelease(void) \
|
|
{ \
|
|
if (m_iptr) \
|
|
{ \
|
|
m_iptr->Release(); \
|
|
m_iptr = NULL; \
|
|
} \
|
|
} \
|
|
\
|
|
void SimpleRelease(void) \
|
|
{ \
|
|
ASSERT(m_iptr != NULL); \
|
|
m_iptr->Release(); \
|
|
m_iptr = NULL; \
|
|
} \
|
|
\
|
|
void Attach(Interface* iptr) \
|
|
{ \
|
|
ASSERT(m_iptr == NULL); \
|
|
m_iptr = iptr; \
|
|
} \
|
|
\
|
|
void Detach(void) \
|
|
{ \
|
|
m_iptr = NULL; \
|
|
} \
|
|
\
|
|
Interface * operator-> () { return m_iptr; } \
|
|
Interface& operator * () { return *m_iptr; } \
|
|
operator Interface *() { return m_iptr; } \
|
|
\
|
|
Interface ** operator &() \
|
|
{ \
|
|
ASSERT(m_iptr == NULL); \
|
|
return &m_iptr; \
|
|
} \
|
|
\
|
|
Interface *Self(void) { return m_iptr; } \
|
|
\
|
|
private: \
|
|
void operator= (const cls &) {;} \
|
|
cls(const cls &){;}
|
|
|
|
|
|
|
|
|
|
//____________________________________________________________________________
|
|
//
|
|
// Macro: EXCEPTION HANDLING MACROS
|
|
//
|
|
// Purpose: Provide standard macros for exception-handling in
|
|
// OLE servers.
|
|
//
|
|
// History: 7/23/1996 JonN Created
|
|
//
|
|
// Notes: Declare USE_HANDLE_MACROS("Component name") in each source
|
|
// file before these are used.
|
|
//
|
|
// These macros can only be used in function calls which return
|
|
// type HRESULT.
|
|
//
|
|
// Bracket routines which can generate exceptions
|
|
// with STANDARD_TRY and STANDARD_CATCH.
|
|
//
|
|
// Where these routines are COM methods requiring MFC
|
|
// support, use MFC_TRY and MFC_CATCH instead.
|
|
//____________________________________________________________________________
|
|
//
|
|
|
|
|
|
#define USE_HANDLE_MACROS(component) \
|
|
static TCHAR* You_forgot_to_declare_USE_HANDLE_MACROS = _T(component);
|
|
|
|
#define STANDARD_TRY \
|
|
try {
|
|
|
|
#define MFC_TRY \
|
|
AFX_MANAGE_STATE(AfxGetStaticModuleState( )); \
|
|
STANDARD_TRY
|
|
|
|
|
|
// ISSUE-2002/04/01-JonN remove ENDMETHOD_READBLOCK
|
|
|
|
//
|
|
// CODEWORK don't quite have ENDMETHOD_READBLOCK working yet
|
|
//
|
|
#ifdef DEBUG
|
|
#define ENDMETHOD_STRING \
|
|
"%s: The unexpected error can be identified as \"%s\" context %n\n"
|
|
#define ENDMETHOD_READBLOCK \
|
|
{ \
|
|
TCHAR szError[MAX_PATH]; \
|
|
UINT nHelpContext = 0; \
|
|
if ( e->GetErrorMessage( szError, MAX_PATH, &nHelpContext ) ) \
|
|
{ \
|
|
TRACE( ENDMETHOD_STRING, \
|
|
You_forgot_to_declare_USE_HANDLE_MACROS, \
|
|
szError, \
|
|
nHelpContext ); \
|
|
} \
|
|
}
|
|
#else
|
|
#define ENDMETHOD_READBLOCK
|
|
#endif
|
|
|
|
#define ERRSTRING_MEMORY "%s: An out-of-memory error occurred\n"
|
|
#define ERRSTRING_FILE "%s: File error 0x%lx occurred on file \"%s\"\n"
|
|
#define ERRSTRING_OLE "%s: OLE error 0x%lx occurred\n"
|
|
#define ERRSTRING_UNEXPECTED "%s: An unexpected error occurred\n"
|
|
#define BADPARM_STRING "%s: Bad string parameter\n"
|
|
#define BADPARM_POINTER "%s: Bad pointer parameter\n"
|
|
|
|
#define TRACEERR(s) TRACE( s, You_forgot_to_declare_USE_HANDLE_MACROS )
|
|
#define TRACEERR1(s,a) TRACE( s, You_forgot_to_declare_USE_HANDLE_MACROS,a )
|
|
#define TRACEERR2(s,a,b) TRACE( s, You_forgot_to_declare_USE_HANDLE_MACROS,a,b )
|
|
|
|
// Note that it is important to use "e->Delete();" and not "delete e;"
|
|
#define STANDARD_CATCH \
|
|
} \
|
|
catch (CMemoryException* e) \
|
|
{ \
|
|
TRACEERR( ERRSTRING_MEMORY ); \
|
|
ASSERT( FALSE ); \
|
|
e->Delete(); \
|
|
return E_OUTOFMEMORY; \
|
|
} \
|
|
catch (COleException* e) \
|
|
{ \
|
|
HRESULT hr = (HRESULT)e->Process(e); \
|
|
TRACEERR1( ERRSTRING_OLE, hr ); \
|
|
ASSERT( FALSE ); \
|
|
e->Delete(); \
|
|
ASSERT( FAILED(hr) ); \
|
|
return hr; \
|
|
} \
|
|
catch (CFileException* e) \
|
|
{ \
|
|
HRESULT hr = (HRESULT)e->m_lOsError; \
|
|
TRACEERR2( ERRSTRING_FILE, hr, e->m_strFileName ); \
|
|
ASSERT( FALSE ); \
|
|
e->Delete(); \
|
|
ASSERT( FAILED(hr) ); \
|
|
return hr; \
|
|
} \
|
|
catch (CException* e) \
|
|
{ \
|
|
TRACEERR( ERRSTRING_UNEXPECTED ); \
|
|
ASSERT( FALSE ); \
|
|
e->Delete(); \
|
|
return E_UNEXPECTED; \
|
|
}
|
|
|
|
#define MFC_CATCH \
|
|
STANDARD_CATCH
|
|
|
|
#define TEST_STRING_PARAM(x) \
|
|
if ( (x) != NULL && !AfxIsValidString(x) ) { \
|
|
TRACEERR( BADPARM_STRING ); return E_POINTER; }
|
|
#define TEST_NONNULL_STRING_PARAM(x) \
|
|
if ( !AfxIsValidString(x) ) { \
|
|
TRACEERR( BADPARM_STRING ); return E_POINTER; }
|
|
#define TEST_NONNULL_PTR_PARAM(x) \
|
|
if ( (x) == NULL || IsBadWritePtr((x),sizeof(x)) ) { \
|
|
TRACEERR( BADPARM_POINTER ); return E_POINTER; }
|
|
|
|
#endif // _MACROS_H_
|