732 lines
21 KiB
C
732 lines
21 KiB
C
|
/* This file is part of the source code for the DispHelper COM helper library.
|
||
|
* DispHelper allows you to call COM objects with an extremely simple printf style syntax.
|
||
|
* DispHelper can be used from C++ or even plain C. It works with most Windows compilers
|
||
|
* including Dev-CPP, Visual C++ and LCC-WIN32. Including DispHelper in your project
|
||
|
* couldn't be simpler as it is available in a compacted single file version.
|
||
|
*
|
||
|
* Included with DispHelper are over 20 samples that demonstrate using COM objects
|
||
|
* including ADO, CDO, Outlook, Eudora, Excel, Word, Internet Explorer, MSHTML,
|
||
|
* PocketSoap, Word Perfect, MS Agent, SAPI, MSXML, WIA, dexplorer and WMI.
|
||
|
*
|
||
|
* DispHelper is free open source software provided under the BSD license.
|
||
|
*
|
||
|
* Find out more and download DispHelper at:
|
||
|
* http://sourceforge.net/projects/disphelper/
|
||
|
* http://disphelper.sourceforge.net/
|
||
|
*/
|
||
|
|
||
|
|
||
|
#ifndef DISPHELPER_H_INCLUDED
|
||
|
#define DISPHELPER_H_INCLUDED
|
||
|
|
||
|
#include <objbase.h>
|
||
|
#include <time.h>
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
extern "C" {
|
||
|
#endif
|
||
|
|
||
|
HRESULT dhCreateObject(LPCOLESTR szProgId, LPCWSTR szMachine, IDispatch ** ppDisp);
|
||
|
HRESULT dhGetObject(LPCOLESTR szFile, LPCOLESTR szProgId, IDispatch ** ppDisp);
|
||
|
|
||
|
HRESULT dhCreateObjectEx(LPCOLESTR szProgId, REFIID riid, DWORD dwClsContext, COSERVERINFO * pServerInfo, void ** ppv);
|
||
|
HRESULT dhGetObjectEx(LPCOLESTR szFile, LPCOLESTR szProgId, REFIID riid, DWORD dwClsContext, LPVOID lpvReserved, void ** ppv);
|
||
|
|
||
|
HRESULT dhCallMethod(IDispatch * pDisp, LPCOLESTR szMember, ...);
|
||
|
HRESULT dhPutValue(IDispatch * pDisp, LPCOLESTR szMember, ...);
|
||
|
HRESULT dhPutRef(IDispatch * pDisp, LPCOLESTR szMember, ...);
|
||
|
HRESULT dhGetValue(LPCWSTR szIdentifier, void * pResult, IDispatch * pDisp, LPCOLESTR szMember, ...);
|
||
|
|
||
|
HRESULT dhInvoke(int invokeType, VARTYPE returnType, VARIANT * pvResult, IDispatch * pDisp, LPCOLESTR szMember, ...);
|
||
|
HRESULT dhInvokeArray(int invokeType, VARIANT * pvResult, UINT cArgs, IDispatch * pDisp, LPCOLESTR szMember, VARIANT * pArgs);
|
||
|
|
||
|
HRESULT dhCallMethodV(IDispatch * pDisp, LPCOLESTR szMember, va_list * marker);
|
||
|
HRESULT dhPutValueV(IDispatch * pDisp, LPCOLESTR szMember, va_list * marker);
|
||
|
HRESULT dhPutRefV(IDispatch * pDisp, LPCOLESTR szMember, va_list * marker);
|
||
|
HRESULT dhGetValueV(LPCWSTR szIdentifier, void * pResult, IDispatch * pDisp, LPCOLESTR szMember, va_list * marker);
|
||
|
HRESULT dhInvokeV(int invokeType, VARTYPE returnType, VARIANT * pvResult, IDispatch * pDisp, LPCOLESTR szMember, va_list * marker);
|
||
|
|
||
|
HRESULT dhAutoWrap(int invokeType, VARIANT * pvResult, IDispatch * pDisp, LPCOLESTR szMember, UINT cArgs, ...);
|
||
|
HRESULT dhParseProperties(IDispatch * pDisp, LPCWSTR szProperties, UINT * lpcPropsSet);
|
||
|
|
||
|
HRESULT dhEnumBegin(IEnumVARIANT ** ppEnum, IDispatch * pDisp, LPCOLESTR szMember, ...);
|
||
|
HRESULT dhEnumBeginV(IEnumVARIANT ** ppEnum, IDispatch * pDisp, LPCOLESTR szMember, va_list * marker);
|
||
|
HRESULT dhEnumNextObject(IEnumVARIANT * pEnum, IDispatch ** ppDisp);
|
||
|
HRESULT dhEnumNextVariant(IEnumVARIANT * pEnum, VARIANT * pvResult);
|
||
|
|
||
|
HRESULT dhInitializeImp(BOOL bInitializeCOM, BOOL bUnicode);
|
||
|
void dhUninitialize(BOOL bUninitializeCOM);
|
||
|
|
||
|
#define dhInitializeA(bInitializeCOM) dhInitializeImp(bInitializeCOM, FALSE)
|
||
|
#define dhInitializeW(bInitializeCOM) dhInitializeImp(bInitializeCOM, TRUE)
|
||
|
|
||
|
#ifdef UNICODE
|
||
|
#define dhInitialize dhInitializeW
|
||
|
#else
|
||
|
#define dhInitialize dhInitializeA
|
||
|
#endif
|
||
|
|
||
|
#define AutoWrap dhAutoWrap
|
||
|
#define DISPATCH_OBJ(objName) IDispatch * objName = NULL
|
||
|
#define dhFreeString(string) SysFreeString((BSTR) string)
|
||
|
|
||
|
#ifndef SAFE_RELEASE
|
||
|
#ifdef __cplusplus
|
||
|
#define SAFE_RELEASE(pObj) { if (pObj) { (pObj)->Release(); (pObj) = NULL; } }
|
||
|
#else
|
||
|
#define SAFE_RELEASE(pObj) { if (pObj) { (pObj)->lpVtbl->Release(pObj); (pObj) = NULL; } }
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
#define SAFE_FREE_STRING(string) { dhFreeString(string); (string) = NULL; }
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/* ===================================================================== */
|
||
|
#ifndef DISPHELPER_NO_WITH
|
||
|
|
||
|
#define WITH0(objName, pDisp, szMember) { \
|
||
|
DISPATCH_OBJ(objName); \
|
||
|
if (SUCCEEDED(dhGetValue(L"%o", &objName, pDisp, szMember))) {
|
||
|
|
||
|
#define WITH1(objName, pDisp, szMember, arg1) { \
|
||
|
DISPATCH_OBJ(objName); \
|
||
|
if (SUCCEEDED(dhGetValue(L"%o", &objName, pDisp, szMember, arg1))) {
|
||
|
|
||
|
#define WITH2(objName, pDisp, szMember, arg1, arg2) { \
|
||
|
DISPATCH_OBJ(objName); \
|
||
|
if (SUCCEEDED(dhGetValue(L"%o", &objName, pDisp, szMember, arg1, arg2))) {
|
||
|
|
||
|
#define WITH3(objName, pDisp, szMember, arg1, arg2, arg3) { \
|
||
|
DISPATCH_OBJ(objName); \
|
||
|
if (SUCCEEDED(dhGetValue(L"%o", &objName, pDisp, szMember, arg1, arg2, arg3))) {
|
||
|
|
||
|
#define WITH4(objName, pDisp, szMember, arg1, arg2, arg3, arg4) { \
|
||
|
DISPATCH_OBJ(objName); \
|
||
|
if (SUCCEEDED(dhGetValue(L"%o", &objName, pDisp, szMember, arg1, arg2, arg3, arg4))) {
|
||
|
|
||
|
#define WITH WITH0
|
||
|
|
||
|
#define ON_WITH_ERROR(objName) } else {
|
||
|
|
||
|
#define END_WITH(objName) } SAFE_RELEASE(objName); }
|
||
|
|
||
|
#endif /* ----- DISPHELPER_NO_WITH ----- */
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/* ===================================================================== */
|
||
|
#ifndef DISPHELPER_NO_FOR_EACH
|
||
|
|
||
|
#define FOR_EACH0(objName, pDisp, szMember) { \
|
||
|
IEnumVARIANT * xx_pEnum_xx = NULL; \
|
||
|
DISPATCH_OBJ(objName); \
|
||
|
if (SUCCEEDED(dhEnumBegin(&xx_pEnum_xx, pDisp, szMember))) { \
|
||
|
while (dhEnumNextObject(xx_pEnum_xx, &objName) == NOERROR) {
|
||
|
|
||
|
#define FOR_EACH1(objName, pDisp, szMember, arg1) { \
|
||
|
IEnumVARIANT * xx_pEnum_xx = NULL; \
|
||
|
DISPATCH_OBJ(objName); \
|
||
|
if (SUCCEEDED(dhEnumBegin(&xx_pEnum_xx, pDisp, szMember, arg1))) { \
|
||
|
while (dhEnumNextObject(xx_pEnum_xx, &objName) == NOERROR) {
|
||
|
|
||
|
#define FOR_EACH2(objName, pDisp, szMember, arg1, arg2) { \
|
||
|
IEnumVARIANT * xx_pEnum_xx = NULL; \
|
||
|
DISPATCH_OBJ(objName); \
|
||
|
if (SUCCEEDED(dhEnumBegin(&xx_pEnum_xx, pDisp, szMember, arg1, arg2))) { \
|
||
|
while (dhEnumNextObject(xx_pEnum_xx, &objName) == NOERROR) {
|
||
|
|
||
|
|
||
|
#define FOR_EACH3(objName, pDisp, szMember, arg1, arg2, arg3) { \
|
||
|
IEnumVARIANT * xx_pEnum_xx = NULL; \
|
||
|
DISPATCH_OBJ(objName); \
|
||
|
if (SUCCEEDED(dhEnumBegin(&xx_pEnum_xx, pDisp, szMember, arg1, arg2, arg3))) { \
|
||
|
while (dhEnumNextObject(xx_pEnum_xx, &objName) == NOERROR) {
|
||
|
|
||
|
|
||
|
#define FOR_EACH4(objName, pDisp, szMember, arg1, arg2, arg3, arg4) { \
|
||
|
IEnumVARIANT * xx_pEnum_xx = NULL; \
|
||
|
DISPATCH_OBJ(objName); \
|
||
|
if (SUCCEEDED(dhEnumBegin(&xx_pEnum_xx, pDisp, szMember, arg1, arg2, arg3, arg4))) { \
|
||
|
while (dhEnumNextObject(xx_pEnum_xx, &objName) == NOERROR) {
|
||
|
|
||
|
#define FOR_EACH FOR_EACH0
|
||
|
|
||
|
#define ON_FOR_EACH_ERROR(objName) SAFE_RELEASE(objName); }} else {{
|
||
|
|
||
|
#define NEXT(objName) SAFE_RELEASE(objName); }} SAFE_RELEASE(objName); SAFE_RELEASE(xx_pEnum_xx); }
|
||
|
|
||
|
#endif /* ----- DISPHELPER_NO_FOR_EACH ----- */
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/* ===================================================================== */
|
||
|
#ifndef DISPHELPER_NO_EXCEPTIONS
|
||
|
|
||
|
/* Structure to store a DispHelper exception */
|
||
|
typedef struct tagDH_EXCEPTION
|
||
|
{
|
||
|
LPCWSTR szInitialFunction;
|
||
|
LPCWSTR szErrorFunction;
|
||
|
|
||
|
HRESULT hr;
|
||
|
|
||
|
WCHAR szMember[64];
|
||
|
WCHAR szCompleteMember[256];
|
||
|
|
||
|
UINT swCode;
|
||
|
LPWSTR szDescription;
|
||
|
LPWSTR szSource;
|
||
|
LPWSTR szHelpFile;
|
||
|
DWORD dwHelpContext;
|
||
|
|
||
|
UINT iArgError;
|
||
|
|
||
|
BOOL bDispatchError;
|
||
|
|
||
|
#ifdef DISPHELPER_INTERNAL_BUILD
|
||
|
BOOL bOld;
|
||
|
#endif
|
||
|
} DH_EXCEPTION, * PDH_EXCEPTION;
|
||
|
|
||
|
typedef void (*DH_EXCEPTION_CALLBACK) (PDH_EXCEPTION);
|
||
|
|
||
|
/* Structure to store exception options. */
|
||
|
typedef struct tagDH_EXCEPTION_OPTIONS
|
||
|
{
|
||
|
HWND hwnd;
|
||
|
LPCWSTR szAppName;
|
||
|
BOOL bShowExceptions;
|
||
|
BOOL bDisableRecordExceptions;
|
||
|
DH_EXCEPTION_CALLBACK pfnExceptionCallback;
|
||
|
} DH_EXCEPTION_OPTIONS, * PDH_EXCEPTION_OPTIONS;
|
||
|
|
||
|
/* Functions to manipulate global exception options */
|
||
|
HRESULT dhToggleExceptions(BOOL bShow);
|
||
|
HRESULT dhSetExceptionOptions(PDH_EXCEPTION_OPTIONS pExceptionOptions);
|
||
|
HRESULT dhGetExceptionOptions(PDH_EXCEPTION_OPTIONS pExceptionOptions);
|
||
|
|
||
|
/* Functions to show an exception, format an exception into a string
|
||
|
* and get a copy of the last exception */
|
||
|
HRESULT dhShowException(PDH_EXCEPTION pException);
|
||
|
HRESULT dhGetLastException(PDH_EXCEPTION * pException);
|
||
|
HRESULT dhFormatExceptionW(PDH_EXCEPTION pException, LPWSTR szBuffer, UINT cchBufferSize, BOOL bFixedFont);
|
||
|
HRESULT dhFormatExceptionA(PDH_EXCEPTION pException, LPSTR szBuffer, UINT cchBufferSize, BOOL bFixedFont);
|
||
|
|
||
|
#ifdef UNICODE
|
||
|
#define dhFormatException dhFormatExceptionW
|
||
|
#else
|
||
|
#define dhFormatException dhFormatExceptionA
|
||
|
#endif
|
||
|
|
||
|
#ifdef DISPHELPER_INTERNAL_BUILD
|
||
|
|
||
|
void dhEnter(void);
|
||
|
HRESULT dhExitEx(HRESULT hr, BOOL bDispatchError, LPCWSTR szMember, LPCWSTR szCompleteMember, EXCEPINFO * pExcepInfo, UINT iArgError, LPCWSTR szFunctionName);
|
||
|
void dhCleanupThreadException(void);
|
||
|
|
||
|
#define DH_ENTER(szFunctionName) static LPCWSTR xx_szFunctionName_xx = szFunctionName; \
|
||
|
dhEnter()
|
||
|
|
||
|
#define DH_EXITEX(hr, bDispatchError, szMember, szCompleteMember, pExcepInfo, iArgError) \
|
||
|
dhExitEx(hr, bDispatchError, szMember, szCompleteMember, pExcepInfo, iArgError, xx_szFunctionName_xx)
|
||
|
|
||
|
#define DH_EXIT(hr, szCompleteMember) DH_EXITEX(hr, FALSE, NULL, szCompleteMember, NULL, 0)
|
||
|
|
||
|
#endif /* ----- DISPHELPER_INTERNAL_BUILD ----- */
|
||
|
|
||
|
#else /* ----- DISPHELPER_NO_EXCEPTIONS ----- */
|
||
|
|
||
|
/* These macros define out calls to selected exception functions */
|
||
|
#define dhToggleExceptions(bShow) (E_NOTIMPL)
|
||
|
#define dhSetExceptionOptions(pExcepOptions) (E_NOTIMPL)
|
||
|
|
||
|
#ifdef DISPHELPER_INTERNAL_BUILD
|
||
|
#define DH_ENTER(szFunctionName)
|
||
|
#define DH_EXITEX(hr, bDispatchError, szMember, szCompleteMember, pExcepInfo, iArgError) \
|
||
|
(((hr == DISP_E_EXCEPTION && pExcepInfo) ? \
|
||
|
(SysFreeString(((EXCEPINFO *)(pExcepInfo))->bstrSource), \
|
||
|
SysFreeString(((EXCEPINFO *)(pExcepInfo))->bstrDescription), \
|
||
|
SysFreeString(((EXCEPINFO *)(pExcepInfo))->bstrHelpFile), 0) : (0)), hr)
|
||
|
#define DH_EXIT(hr, szCompleteMember)(hr)
|
||
|
#endif
|
||
|
|
||
|
#endif /* ----- DISPHELPER_NO_EXCEPTIONS ----- */
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/* ===================================================================== */
|
||
|
#ifdef DISPHELPER_INTERNAL_BUILD
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdarg.h>
|
||
|
#include <wchar.h>
|
||
|
|
||
|
/* Macro to include or lose debug code. */
|
||
|
#ifdef DEBUG
|
||
|
#define DBG_CODE(code) code
|
||
|
#else
|
||
|
#define DBG_CODE(code)
|
||
|
#endif
|
||
|
|
||
|
/* Are we in unicode mode? */
|
||
|
extern BOOL dh_g_bIsUnicodeMode;
|
||
|
|
||
|
/* Number of objects in an array */
|
||
|
#undef ARRAYSIZE
|
||
|
#define ARRAYSIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||
|
|
||
|
/* Maximum number of arguments for a member */
|
||
|
#define DH_MAX_ARGS 25
|
||
|
|
||
|
/* Maximum length of a member string */
|
||
|
#define DH_MAX_MEMBER 512
|
||
|
|
||
|
/* This macro is missing from Dev-Cpp/Mingw */
|
||
|
#ifndef V_UI4
|
||
|
#define V_UI4(X) V_UNION(X, ulVal)
|
||
|
#endif
|
||
|
|
||
|
/* Macro to notify programmer of invalid identifier in debug mode. */
|
||
|
#define DEBUG_NOTIFY_INVALID_IDENTIFIER(chIdentifier) \
|
||
|
DBG_CODE( { \
|
||
|
char buf[256]; \
|
||
|
sprintf(buf,"DEBUG: The format string or return identifier contained the invalid identifier '%c'.\n" \
|
||
|
"The valid identifiers are \"d/u/e/b/v/B/S/s/T/o/O/t/W/D/f/m\".\n" \
|
||
|
"Each %% character should be followed by a valid identifier.\n" \
|
||
|
"Identifiers are case sensitive.", (chIdentifier)); \
|
||
|
MessageBoxA(NULL, buf, "DEBUG: Invalid Format Identifier", MB_ICONSTOP); \
|
||
|
} )
|
||
|
|
||
|
#ifdef _MSC_VER
|
||
|
#pragma warning(disable : 4706) /* Assignment in conditional expression */
|
||
|
#endif
|
||
|
|
||
|
#ifndef DISPHELPER_NO_PRAGMA_LIB
|
||
|
#ifdef __LCC__
|
||
|
#pragma lib <ole32.lib>
|
||
|
#pragma lib <oleaut32.lib>
|
||
|
#pragma lib <uuid.lib>
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
|
||
|
#endif /* ----- DISPHELPER_INTERNAL_BUILD ----- */
|
||
|
|
||
|
#ifndef DISPHELPER_NO_PRAGMA_LIB
|
||
|
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||
|
#pragma comment(lib, "ole32.lib")
|
||
|
#pragma comment(lib, "oleaut32.lib")
|
||
|
#pragma comment(lib, "uuid.lib")
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/* ===================================================================== */
|
||
|
#if defined(__cplusplus) && !defined(DISPHELPER_NO_CPP_EXTENSIONS)
|
||
|
|
||
|
#include <iostream>
|
||
|
#include <string>
|
||
|
|
||
|
#ifdef _MSC_VER
|
||
|
#pragma warning( disable : 4290 ) /* throw() specification ignored */
|
||
|
#endif
|
||
|
|
||
|
#ifndef DISPHELPER_USE_MS_SMART_PTR
|
||
|
|
||
|
template <class T>
|
||
|
class CDhComPtr
|
||
|
{
|
||
|
public:
|
||
|
CDhComPtr() throw() : m_pInterface (NULL) {}
|
||
|
|
||
|
CDhComPtr(T* pInterface) throw() : m_pInterface (pInterface)
|
||
|
{
|
||
|
if (m_pInterface) m_pInterface->AddRef();
|
||
|
}
|
||
|
|
||
|
CDhComPtr(const CDhComPtr& original) throw() : m_pInterface (original.m_pInterface)
|
||
|
{
|
||
|
if (m_pInterface) m_pInterface->AddRef();
|
||
|
}
|
||
|
|
||
|
~CDhComPtr() throw()
|
||
|
{
|
||
|
Dispose();
|
||
|
}
|
||
|
|
||
|
void Dispose() throw()
|
||
|
{
|
||
|
if (m_pInterface)
|
||
|
{
|
||
|
m_pInterface->Release();
|
||
|
m_pInterface = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
T* Detach() throw()
|
||
|
{
|
||
|
T* temp = m_pInterface;
|
||
|
m_pInterface = NULL;
|
||
|
return temp;
|
||
|
}
|
||
|
|
||
|
inline operator T*() const throw()
|
||
|
{
|
||
|
return m_pInterface;
|
||
|
}
|
||
|
|
||
|
T** operator&() throw()
|
||
|
{
|
||
|
Dispose();
|
||
|
return &m_pInterface;
|
||
|
}
|
||
|
|
||
|
T* operator->() const throw(HRESULT)
|
||
|
{
|
||
|
if (!m_pInterface) throw E_POINTER;
|
||
|
return m_pInterface;
|
||
|
}
|
||
|
|
||
|
CDhComPtr& operator=(T* pInterface) throw()
|
||
|
{
|
||
|
if (m_pInterface != pInterface)
|
||
|
{
|
||
|
T* pOldInterface = m_pInterface;
|
||
|
m_pInterface = pInterface;
|
||
|
if (m_pInterface) m_pInterface->AddRef();
|
||
|
if (pOldInterface) pOldInterface->Release();
|
||
|
}
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
CDhComPtr& operator=(const int null) throw(HRESULT)
|
||
|
{
|
||
|
if (null != 0) throw(E_POINTER);
|
||
|
return operator=((T*) NULL);
|
||
|
}
|
||
|
|
||
|
CDhComPtr& operator=(const CDhComPtr& rhs) throw()
|
||
|
{
|
||
|
return operator=(rhs.m_pInterface);
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
T* m_pInterface;
|
||
|
};
|
||
|
|
||
|
typedef CDhComPtr<IDispatch> CDispPtr;
|
||
|
typedef CDhComPtr<IEnumVARIANT> CEnumPtr;
|
||
|
typedef CDhComPtr<IUnknown> CUnknownPtr;
|
||
|
|
||
|
#else /* DISPHELPER_USE_MS_SMART_PTR */
|
||
|
|
||
|
#include <comdef.h>
|
||
|
typedef IDispatchPtr CDispPtr;
|
||
|
typedef IEnumVARIANTPtr CEnumPtr;
|
||
|
typedef IUnknownPtr CUnknownPtr;
|
||
|
|
||
|
#endif /* DISPHELPER_USE_MS_SMART_PTR */
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/* ===================================================================== */
|
||
|
template <class T>
|
||
|
class CDhStringTemplate
|
||
|
{
|
||
|
public:
|
||
|
CDhStringTemplate() throw() : m_strptr (NULL) {}
|
||
|
|
||
|
CDhStringTemplate(const CDhStringTemplate& original) throw()
|
||
|
{
|
||
|
Copy(original.m_strptr);
|
||
|
}
|
||
|
|
||
|
CDhStringTemplate(const int null) throw(HRESULT) : m_strptr (NULL)
|
||
|
{
|
||
|
if (null != 0) throw(E_POINTER);
|
||
|
}
|
||
|
|
||
|
~CDhStringTemplate() throw()
|
||
|
{
|
||
|
Dispose();
|
||
|
}
|
||
|
|
||
|
void Dispose() throw()
|
||
|
{
|
||
|
dhFreeString(m_strptr);
|
||
|
m_strptr = NULL;
|
||
|
}
|
||
|
|
||
|
T* Detach() throw()
|
||
|
{
|
||
|
T* temp = m_strptr;
|
||
|
m_strptr = NULL;
|
||
|
return temp;
|
||
|
}
|
||
|
|
||
|
T** operator&() throw()
|
||
|
{
|
||
|
Dispose();
|
||
|
return &m_strptr;
|
||
|
}
|
||
|
|
||
|
inline operator T*() const throw()
|
||
|
{
|
||
|
return m_strptr;
|
||
|
}
|
||
|
|
||
|
inline T& operator[](int nIndex) const throw()
|
||
|
{
|
||
|
return m_strptr[nIndex];
|
||
|
}
|
||
|
|
||
|
CDhStringTemplate& operator=(const CDhStringTemplate& rhs)
|
||
|
{
|
||
|
if (m_strptr != rhs.m_strptr)
|
||
|
{
|
||
|
T* temp = m_strptr;
|
||
|
Copy(rhs.m_strptr);
|
||
|
dhFreeString(temp);
|
||
|
}
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
CDhStringTemplate& operator=(const int null) throw(HRESULT)
|
||
|
{
|
||
|
if (null != 0) throw(E_POINTER);
|
||
|
Dispose();
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
void Copy(const T* rhs)
|
||
|
{
|
||
|
if (rhs == NULL)
|
||
|
{
|
||
|
m_strptr = NULL;
|
||
|
}
|
||
|
else if (sizeof(T) == sizeof(CHAR))
|
||
|
{
|
||
|
m_strptr = (T*) SysAllocStringByteLen((LPCSTR) rhs, SysStringByteLen((BSTR) rhs));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_strptr = (T*) SysAllocStringLen((OLECHAR *) rhs, SysStringLen((BSTR) rhs));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
T* m_strptr;
|
||
|
};
|
||
|
|
||
|
typedef CDhStringTemplate<CHAR> CDhStringA; /* Ansi string - LPSTR */
|
||
|
typedef CDhStringTemplate<WCHAR> CDhStringW; /* Unicode string - LPWSTR */
|
||
|
typedef CDhStringTemplate<OLECHAR> CDhStringB; /* Unicode bstring - BSTR */
|
||
|
typedef CDhStringTemplate<TCHAR> CDhStringT; /* T string - LPTSTR */
|
||
|
typedef CDhStringTemplate<TCHAR> CDhString; /* T string - LPTSTR */
|
||
|
|
||
|
inline std::ostream& operator<<(std::ostream& os, const CDhStringA& s)
|
||
|
{
|
||
|
return os << (s ? s : (char*) "(null)");
|
||
|
}
|
||
|
|
||
|
//inline std::wostream& operator<<(std::wostream& os, const CDhStringW& s)
|
||
|
//{
|
||
|
// return os << (s ? s : (wchar_t*) L"(null)");
|
||
|
//}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/* ===================================================================== */
|
||
|
class CDhInitialize
|
||
|
{
|
||
|
public:
|
||
|
CDhInitialize(const BOOL bInitCom = TRUE) throw() : m_bInitCom (bInitCom)
|
||
|
{
|
||
|
dhInitialize(m_bInitCom);
|
||
|
}
|
||
|
|
||
|
~CDhInitialize() throw()
|
||
|
{
|
||
|
dhUninitialize(m_bInitCom);
|
||
|
}
|
||
|
private:
|
||
|
BOOL m_bInitCom;
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/* ===================================================================== */
|
||
|
#ifndef DISPHELPER_NO_EXCEPTIONS
|
||
|
class dhThrowFunctions
|
||
|
{
|
||
|
public:
|
||
|
static void throw_string() throw(std::string)
|
||
|
{
|
||
|
CHAR szMessage[512];
|
||
|
dhFormatExceptionA(NULL, szMessage, sizeof(szMessage)/sizeof(szMessage[0]), TRUE);
|
||
|
throw std::string(szMessage);
|
||
|
}
|
||
|
|
||
|
static void throw_wstring() throw(std::wstring)
|
||
|
{
|
||
|
WCHAR szMessage[512];
|
||
|
dhFormatExceptionW(NULL, szMessage, sizeof(szMessage)/sizeof(szMessage[0]), TRUE);
|
||
|
throw std::wstring(szMessage);
|
||
|
}
|
||
|
|
||
|
static void throw_dhexception() throw(PDH_EXCEPTION)
|
||
|
{
|
||
|
PDH_EXCEPTION pException = NULL;
|
||
|
dhGetLastException(&pException);
|
||
|
throw pException;
|
||
|
}
|
||
|
};
|
||
|
#endif /* DISPHELPER_NO_EXCEPTIONS */
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/* ===================================================================== */
|
||
|
#ifndef DISPHELPER_NO_EXCEPTIONS
|
||
|
inline bool dhIfFailThrowString(HRESULT hr) throw(std::string)
|
||
|
{
|
||
|
if (FAILED(hr)) dhThrowFunctions::throw_string();
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
inline bool dhIfFailThrowWString(HRESULT hr) throw(std::wstring)
|
||
|
{
|
||
|
if (FAILED(hr)) dhThrowFunctions::throw_wstring();
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
inline bool dhIfFailThrowDhException(HRESULT hr) throw(PDH_EXCEPTION)
|
||
|
{
|
||
|
if (FAILED(hr)) dhThrowFunctions::throw_dhexception();
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
#define dhCheck dhIfFailThrowString
|
||
|
|
||
|
#endif /* DISPHELPER_NO_EXCEPTIONS */
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/* ===================================================================== */
|
||
|
#ifndef DISPHELPER_NO_WITH
|
||
|
|
||
|
#undef WITH0
|
||
|
#define WITH0(objName, pDisp, szMember) { \
|
||
|
CDispPtr objName; \
|
||
|
if (SUCCEEDED(dhGetValue(L"%o", &objName, pDisp, szMember))) {
|
||
|
|
||
|
#undef WITH1
|
||
|
#define WITH1(objName, pDisp, szMember, arg1) { \
|
||
|
CDispPtr objName; \
|
||
|
if (SUCCEEDED(dhGetValue(L"%o", &objName, pDisp, szMember, arg1))) {
|
||
|
|
||
|
#undef WITH2
|
||
|
#define WITH2(objName, pDisp, szMember, arg1, arg2) { \
|
||
|
CDispPtr objName; \
|
||
|
if (SUCCEEDED(dhGetValue(L"%o", &objName, pDisp, szMember, arg1, arg2))) {
|
||
|
|
||
|
#undef WITH3
|
||
|
#define WITH3(objName, pDisp, szMember, arg1, arg2, arg3) { \
|
||
|
CDispPtr objName; \
|
||
|
if (SUCCEEDED(dhGetValue(L"%o", &objName, pDisp, szMember, arg1, arg2, arg3))) {
|
||
|
|
||
|
#undef WITH4
|
||
|
#define WITH4(objName, pDisp, szMember, arg1, arg2, arg3, arg4) { \
|
||
|
CDispPtr objName; \
|
||
|
if (SUCCEEDED(dhGetValue(L"%o", &objName, pDisp, szMember, arg1, arg2, arg3, arg4))) {
|
||
|
|
||
|
#undef ON_WITH_ERROR
|
||
|
#define ON_WITH_ERROR(objName) } else {
|
||
|
|
||
|
#undef END_WITH
|
||
|
#define END_WITH(objName) }}
|
||
|
|
||
|
#define END_WITH_THROW(objName) } else { dhThrowFunctions::throw_string(); }}
|
||
|
|
||
|
#endif /* DISPHELPER_NO_WITH */
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/* ===================================================================== */
|
||
|
#ifndef DISPHELPER_NO_FOR_EACH
|
||
|
|
||
|
#undef FOR_EACH0
|
||
|
#define FOR_EACH0(objName, pDisp, szMember) { \
|
||
|
CEnumPtr xx_pEnum_xx; \
|
||
|
if (SUCCEEDED(dhEnumBegin(&xx_pEnum_xx, pDisp, szMember))) { \
|
||
|
CDispPtr objName; \
|
||
|
while (dhEnumNextObject(xx_pEnum_xx, &objName) == NOERROR) {
|
||
|
|
||
|
#undef FOR_EACH1
|
||
|
#define FOR_EACH1(objName, pDisp, szMember, arg1) { \
|
||
|
CEnumPtr xx_pEnum_xx; \
|
||
|
if (SUCCEEDED(dhEnumBegin(&xx_pEnum_xx, pDisp, szMember, arg1))) { \
|
||
|
CDispPtr objName; \
|
||
|
while (dhEnumNextObject(xx_pEnum_xx, &objName) == NOERROR) {
|
||
|
|
||
|
#undef FOR_EACH2
|
||
|
#define FOR_EACH2(objName, pDisp, szMember, arg1, arg2) { \
|
||
|
CEnumPtr xx_pEnum_xx; \
|
||
|
if (SUCCEEDED(dhEnumBegin(&xx_pEnum_xx, pDisp, szMember, arg1, arg2))) { \
|
||
|
CDispPtr objName; \
|
||
|
while (dhEnumNextObject(xx_pEnum_xx, &objName) == NOERROR) {
|
||
|
|
||
|
#undef FOR_EACH3
|
||
|
#define FOR_EACH3(objName, pDisp, szMember, arg1, arg2, arg3) { \
|
||
|
CEnumPtr xx_pEnum_xx; \
|
||
|
if (SUCCEEDED(dhEnumBegin(&xx_pEnum_xx, pDisp, szMember, arg1, arg2, arg3))) { \
|
||
|
CDispPtr objName; \
|
||
|
while (dhEnumNextObject(xx_pEnum_xx, &objName) == NOERROR) {
|
||
|
|
||
|
#undef FOR_EACH4
|
||
|
#define FOR_EACH4(objName, pDisp, szMember, arg1, arg2, arg3, arg4) { \
|
||
|
CEnumPtr xx_pEnum_xx; \
|
||
|
if (SUCCEEDED(dhEnumBegin(&xx_pEnum_xx, pDisp, szMember, arg1, arg2, arg3, arg4))) { \
|
||
|
CDispPtr objName; \
|
||
|
while (dhEnumNextObject(xx_pEnum_xx, &objName) == NOERROR) {
|
||
|
|
||
|
#undef ON_FOR_EACH_ERROR
|
||
|
#define ON_FOR_EACH_ERROR(objName) }} else {{
|
||
|
|
||
|
#undef NEXT
|
||
|
#define NEXT(objName) }}}
|
||
|
|
||
|
#define NEXT_THROW(objName) }} else { dhThrowFunctions::throw_string(); }}
|
||
|
|
||
|
#endif /* DISPHELPER_NO_FOR_EACH */
|
||
|
|
||
|
#ifdef _MSC_VER
|
||
|
#pragma warning( default : 4290 )
|
||
|
#endif
|
||
|
|
||
|
#endif /* defined(__cplusplus) && !defined(DISPHELPER_NO_CPP_EXTENSIONS) */
|
||
|
|
||
|
#endif /* ----- DISPHELPER_H_INCLUDED ----- */
|