📄 utility.h
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
//+----------------------------------------------------------------------------
//
//
// File:
// Utility.h
//
// Contents:
//
// Various utilities
//
//-----------------------------------------------------------------------------
#ifndef __UTILITY_H_INCLUDED__
#define __UTILITY_H_INCLUDED__
//////////////////////////////////////////////////
// Various constants
#define INITIAL_REFERENCE (1)
#ifndef ONEK
#define ONEK 1024
#endif
#ifndef FOURK
#define FOURK 4096
#endif
//////////////////////////////////////////////////
// wsprintf isn't supported on Windows 9x, raise compile time error
#ifdef wsprintf
#undef wsprintf
#endif
#define wsprintf __WIN9X_DOESN_T_SUPPORT_WSPRINTF__
//////////////////////////////////////////////////
// Macros
#ifndef UNDER_CE
#define offsetof(c,m) ( reinterpret_cast<size_t>(&(reinterpret_cast<c*>(0))->m) )
#endif
#define countof(a) (sizeof(a)/sizeof(a[0]))
#define maxindex(a) (countof(a) - 1)
#define char_array_size(a) (sizeof(a) - sizeof(a[0]))
#define STRING(x) #x
#define REGKEY(x) "{" STRING(x) "}"
#define MIN(a, b) ((a <= b) ? a : b )
//////////////////////////////////////////////////
// Object counter
#define OBJECT_CREATED() { ::AtomicIncrement(reinterpret_cast<LPLONG>(&g_cObjects)); TRACEL((10, "Creating Object (%i)\n", g_cObjects)); }
#define OBJECT_DELETED() { ::AtomicDecrement(reinterpret_cast<LPLONG>(&g_cObjects)); TRACEL((10, "Deleting Object (%i)\n", g_cObjects)); }
//////////////////////////////////////////////////
// Error handling
#define CHK(err) { hr = (err); if (FAILED(hr)) { goto Cleanup; } }
#define CHK_ARG(arg) { if (!(arg)) return E_INVALIDARG; }
#define CHK_MEM(ptr) CHK_BOOL((ptr) != NULL, E_OUTOFMEMORY)
#define CHK_BOOL(cond, err) { if (!(cond)) { hr = (err); goto Cleanup; } }
#define SETHR_BOOL(cond, err) { if (!(cond)) {hr = (err);} }
//////////////////////////////////////////////////
// Interface Riders
struct InterfaceRiderElement
{
const IID *pIID;
DWORD offs;
};
struct InterfaceRider
{
LONG elc;
const InterfaceRiderElement *elv;
};
#define NULL_POINTER 8
#define class_offset(class, base) \
(reinterpret_cast<DWORD>(static_cast<base*>(reinterpret_cast<class*>(NULL_POINTER))) - NULL_POINTER)
#define DECLARE_INTERFACE_MAP \
protected: \
static const InterfaceRiderElement s_InterfaceRiderElements[]; \
static const InterfaceRider s_InterfaceRider
#define BEGIN_INTERFACE_MAP(class) \
const InterfaceRiderElement class::s_InterfaceRiderElements[] = {
#define ADD_IUNKNOWN(class, interface) \
{ &__uuidof(IUnknown), class_offset(class, interface) },
#define ADD_INTERFACE(class, interface) \
{ & __uuidof(interface), class_offset(class, interface) },
#define END_INTERFACE_MAP(class) \
}; \
const InterfaceRider class::s_InterfaceRider = \
{ countof(class::s_InterfaceRiderElements), class::s_InterfaceRiderElements };
HRESULT QueryInterfaceRider(const InterfaceRider *pRider, void *pvThis, REFIID iid, void **ppvObject);
#define QUERYINTERFACE(iid, ppvObject) \
::QueryInterfaceRider(& s_InterfaceRider, static_cast<void*>(static_cast<T *>(this)), iid, ppvObject)
//////////////////////////////////////////////////
// Class creation support
struct FactoryProduct
{
const CLSID *pCLSID;
HRESULT (WINAPI *pCtorA)(IUnknown *pUnkOuter, REFIID riid, void **ppvObject);
HRESULT (WINAPI *pCtorN)(IUnknown *pUnkOuter, REFIID riid, void **ppvObject);
};
struct FactoryRider
{
LONG elc;
const FactoryProduct *elv;
};
#define DECLARE_FACTORY_MAP \
static const FactoryProduct s_FactoryProducts[]; \
static const FactoryRider s_FactoryRider
#define BEGIN_FACTORY_MAP(class) \
const FactoryProduct class::s_FactoryProducts[] = {
#define ADD_FACTORY_PRODUCT(clsid, class) \
{ &clsid, CSoapAggObject< class >::CreateObject, CSoapObject< class >::CreateObject },
#define ADD_FACTORY_PRODUCT_FTM(clsid, class) \
{ &clsid, CSoapAggObjectFtm< class >::CreateObject, CSoapObjectFtm< class >::CreateObject },
#define END_FACTORY_MAP(class) \
};\
const FactoryRider class::s_FactoryRider = \
{ countof(class::s_FactoryProducts), class::s_FactoryProducts };
HRESULT FindFactoryProduct(REFCLSID rclsid, const FactoryRider *pFactoryRider, const FactoryProduct **ppFactProd);
#define FIND_FACTORY_PRODUCT(rclsid, ppFactProd) \
::FindFactoryProduct(rclsid, &s_FactoryRider, ppFactProd)
//////////////////////////////////////////////////
// string conversion macro
#define CONVERT_WIDECHAR_TO_MULTIBYTE_(cp, what, where) \
{ \
int size = ::WideCharToMultiByte(cp, 0, what, ::SysStringLen(what), 0, 0, 0, 0); \
if(! size) \
{ \
hr = E_INVALIDARG; \
goto Cleanup; \
} \
where = reinterpret_cast<LPSTR>(_alloca(size + 1)); \
ASSERT(where); \
::WideCharToMultiByte(cp, 0, what, ::SysStringLen(what), where, size, 0, 0); \
where[size] = 0; \
}
#define CONVERT_WIDECHAR_TO_MULTIBYTE(what, where) CONVERT_WIDECHAR_TO_MULTIBYTE_(CP_ACP, what, where)
#define CONVERT_WIDECHAR_TO_UTF8(what, where) \
{ \
UINT uiCodePage = CP_UTF8; \
int size; \
if(NULL == what) { \
hr = E_INVALIDARG; \
goto Cleanup; \
} \
if(0 != wcslen(what)) { \
size = ::WideCharToMultiByte(uiCodePage, 0, what, ::SysStringLen(what), 0, 0, 0, 0); \
if(!size) \
{ \
uiCodePage = CP_ACP; \
size = ::WideCharToMultiByte(uiCodePage, 0, what, ::SysStringLen(what), 0, 0, 0, 0); \
} \
if(!size) \
{ \
hr = E_INVALIDARG; \
goto Cleanup; \
} \
} else { \
size = 0; \
} \
where = reinterpret_cast<LPSTR>(_alloca(size + 1)); \
ASSERT(where); \
::WideCharToMultiByte(uiCodePage, 0, what, ::SysStringLen(what), where, size, 0, 0); \
where[size] = 0; \
}
//////////////////////////////////////////////////
// generic helper function to take a source and save a copy of it in target
HRESULT allocateAndCopy(WCHAR ** target, const WCHAR * source);
//////////////////////////////////////////////////
// BSTR helper functions
HRESULT FreeAndCopyBSTR(BSTR &pbstrDst, const WCHAR *pszSrc);
HRESULT FreeAndCopyBSTR(BSTR &pbstrDst, const WCHAR *pszSrc, int length);
HRESULT CopyBSTR(BSTR &pbstrDst, const WCHAR *pszSrc);
HRESULT CopyBSTR(BSTR &pbstrDst, const WCHAR *pszSrc, int length);
HRESULT CatBSTRs(BSTR &pbstrDst, const WCHAR *pStr1, int len1, const WCHAR *pStr2, int len2);
HRESULT FreeAndStoreBSTR(BSTR &bstrDst, const BSTR bstrSrc);
HRESULT AtomicFreeAndCopyBSTR(BSTR &pbstrDst, const WCHAR *pszSrc);
//////////////////////////////////////////////////
// formating helper class
class CAutoFormat
{
public:
CAutoFormat()
{
m_pchBuffer = 0;
m_ulSize = 0;
}
~CAutoFormat()
{
delete [] m_pchBuffer;
}
HRESULT sprintf(const TCHAR *pchFormatString, const TCHAR *pchPartOne);
HRESULT sprintf(const TCHAR *pchFormatString, const TCHAR *pchPartOne, const TCHAR *pchPartTwo);
HRESULT sprintf(const TCHAR *pchFormatString, const TCHAR *pchPartOne, const TCHAR *pchPartTwo, const TCHAR *pchPartThree);
HRESULT sprintf(const TCHAR *pchFormatString, const TCHAR *pchPartOne, const TCHAR *pchPartTwo, const TCHAR *pchPartThree, const TCHAR *pchPartFour);
HRESULT copy(const TCHAR *pchSource);
inline TCHAR * CAutoFormat::operator &(void)
{
return m_pchBuffer;
}
protected:
HRESULT verifyBuffer(ULONG ulNewSize);
TCHAR * m_pchBuffer;
ULONG m_ulSize;
};
#if defined(_M_IX86) && !defined(UNDER_CE)
LONG __stdcall AtomicDecrement(LPLONG lpAddend);
#else
inline LONG AtomicIncrement(LPLONG lpAddend)
{
return InterlockedIncrement(lpAddend);
}
inline LONG AtomicDecrement(LPLONG lpAddend)
{
return InterlockedDecrement(lpAddend);
}
#endif
HRESULT InitSoaputil(void);
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: template<class T> inline T *AssignInterface(T **ppD, T *pS)
//
// parameters:
//
// description:
// Performs interface pointer assignment with necessary AddRef/Release
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class T> inline T *AssignInterface(T **ppD, T *pS)
{
if(pS) pS->AddRef();
if(*ppD) (*ppD)->Release();
return (*ppD) = pS;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// function: inline ULONG ReleaseInterface(const IUnknown *& pUnk)
//
// parameters:
//
// description:
// Safe release of an interface pointer
// returns:
//
////////////////////////////////////////////////////////////////////////////////////////////////////
template <class T> inline ULONG ReleaseInterface(const T *& ppObj)
{
IUnknown *pUnknown = reinterpret_cast<IUnknown *>(InterlockedExchangePointer(&ppObj, 0));
if(pUnknown)
{
return pUnknown->Release();
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template <class T> void release(T ** ppUnk)
{
T * pUnk = *ppUnk;
if (pUnk)
{
*ppUnk = NULL;
pUnk->Release();
}
}
template <class T> void assign(T ** ppUnkDest, T *pUnkSrc)
{
if (ppUnkDest && pUnkSrc)
{
*ppUnkDest = pUnkSrc;
pUnkSrc->AddRef();
}
}
inline void free_bstr(BSTR &p)
{
if (NULL != p)
{
SysFreeString(p);
p = NULL;
}
}
#endif //__UTILITY_H_INCLUDED__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -