📄 utilcls.h
字号:
/////////////////////////////////////////////////////////////////////////////
// UTILCLS.H - COM/ActiveX Utility Classes
//
// (This file provides various COM/ActiveX utility/helper classes that
// (a) Are used by the code generated by C++Builder Import|Typelib|ActiveX files
// (b) Can be used to easily access COM Objects
// (c) Ease COM related tasks such as Initializing OLE, VARIANT wrappers etc.
//
// $Revision: 1.32.1.51 $
// $Date: 31 May 1999 00:00:40 $
//
// Copyright (c) 1998, 1999 Borland International
/////////////////////////////////////////////////////////////////////////////
#ifndef __UTILCLS_H
#define __UTILCLS_H
// To keep track of version of UTILITY class header
//
// This version is checked by the files generated by the TLIBIMP utility or
// via the Import|TypeLibrary and Import|ActiveXControl features of
// C++Builder.
//
// NOTE: Version 0x0101: Shipping C++Builder v4.0
// Version 0x0102: Update to C++Builder v4.0
#define __UTILCLS_H_VERSION 0x0102
#include <objbase.h>
#include <oleauto.h>
#include <cguid.h>
#include <stdarg.h>
#include <tchar.h>
#include <cguid.h>
#include <olectl.h>
// Typedefs to avoid 'simple type expected' error from compiler
//
typedef signed char signed_char;
typedef unsigned char unsigned_char;
typedef unsigned short unsigned_short;
typedef unsigned long unsigned_long;
typedef unsigned __int64 unsigned_int64;
// Forward ref.
//
template <class DISPINTF = IDispatch>
class TAutoDriver;
template <class DISPINTF = IDispatch>
class TDispId;
//////////////////////////////////////////////////////////////////////////////
// Macros
//////////////////////////////////////////////////////////////////////////////
// Until Compiler supports __declspec(uuid(....)) [and __uuidof(...)]
//
#if !defined(DECLSPEC_UUID)
#define DECLSPEC_UUID(guid)
#endif
// CONNECTIONPOINT_ARRAY_SIZE is used by the Fire_xxxx Event templates generated for
// outgoing interfaces in the xxxx_TLB.H file.
//
// Define this macro if you want your server to support more (or less) sinks.
//
#if !defined(CONNECTIONPOINT_ARRAY_SIZE)
#define CONNECTIONPOINT_ARRAY_SIZE 5
#endif
#if !defined(OLETEXT)
#define OLETEXT(x) L ## x
#endif
#if !defined(NO_PROMPT_ON_ASSSERTE_FAILURE)
#define PROMPT_ON_ASSERTE_FAILURE 1
#endif
#if !defined(NO_PROMPT_ON_HRCHECK_FAILURE)
#define PROMPT_ON_HRCHECK_FAILURE 1
#endif
// Implementation of TRACE_HLPR
//
template <class T>
class TDebugHlpr
{
public:
static void __cdecl TRACE_HLPR(T* szFormat, ...);
};
// Helper used to throw an exception
//
template <class T>
void DebugHlpr_THROW(T* msg, HRESULT hr, T* file, bool /*assertFailed*/)
{
#if defined(ComObjHPP)
// NOTE: This does not retrieve rich error information, the way Delphi and VB environments
// do. Eventually this 'throw' will either throw a rich EOleException or some other
// OLE exception class (something equivalent to _com_error, maybe??)
//
// For now, you can specialized [T = TCHAR] 'DebugHlpr_THROW' to retrieve rich error
// information and throw a VCL exception class, if you're using VCL classes already,
// or throw a custom exception class.
//
// NOTE: Use the assertFailed parameter to distinguish between Assertiong and
// OLECHECK failures. (Maybe throw something different??)
throw EOleException(msg, hr, file, _T(""), 0);
#else
throw msg; // Hopefully we never get here: Need something much better to throw!!
#endif
}
// Implementation of OLECHECK - Throw an exception if !SUCCEEDED(hr)
//
template <class T>
HRESULT DebugHlpr_HRCHECK(HRESULT hr, T* expr, T* file, int line)
{
if (!SUCCEEDED(hr))
{
TCHAR szMsg[_MAX_PATH*2];
if (!file)
file = _T("");
LPVOID msg = 0;
if (::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 0, hr,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), LPTSTR(&msg), 0, 0) && (msg != 0))
{
::wsprintf(szMsg, _T("'%s': %s @ %s/%d"), expr, LPTSTR(msg), file, line);
::LocalFree(msg);
}
else
::wsprintf(szMsg, _T("(%s) Error: %lX (%ld) @ %s/%d"), expr, LONG(hr), LONG(hr), file, line);
#if !defined(PROMPT_ON_HRCHECK_FAILURE)
int i = IDYES;
#else
int i = DebugHlpr_PROMPT(_T("HRCHECK: "), szMsg);
#endif
if (i == IDYES)
DebugHlpr_THROW(szMsg, hr, file, false);
else if (i == IDCANCEL)
::DebugBreak();
// NOTE: IDNO - implies we keep chugging along
}
return hr;
}
// _ASSERTE helper return MB_YES, MB_NO or MB_CANCEL
//
template <class T>
int DebugHlpr_ASSERTE(T* expr, T* file, int line)
{
TCHAR msg[_MAX_PATH*2];
::wsprintf(msg, _T("%s @ %s/%d"), LPTSTR(expr), file, line);
#if !defined(PROMPT_ON_ASSERTE_FAILURE)
int i = IDYES;
#else
int i = DebugHlpr_PROMPT(_T("_ASSERTE: "), msg);
#endif
if (i == IDYES)
{
::wsprintf(msg, _T("%s failed - %s/%d"), expr, file, line);
DebugHlpr_THROW(msg, E_FAIL, file, true);
}
return i;
}
// Helper used to display a MessageBox
//
template <class T>
int DebugHlpr_PROMPT(T* caption, T* msg)
{
TCHAR szMsg[_MAX_PATH*2];
wsprintf(szMsg, _T("%s\nPress [Y]es to terminate, [N]o to continue and [C]ancel to Debug"), msg);
return ::MessageBox(0, szMsg, caption, MB_TASKMODAL|MB_ICONQUESTION|MB_YESNOCANCEL);
}
#if !defined(OLETRACE)
#define OLETRACE TDebugHlpr<TCHAR>::TRACE_HLPR
#endif
#if !defined(OLECHECK)
#define OLECHECK(hrexpr) DebugHlpr_HRCHECK(hrexpr, #hrexpr, __FILE__, __LINE__)
#endif
#if !defined(_ASSERTE)
#define _ASSERTE(expr) do { \
if (!(expr) && DebugHlpr_ASSERTE(#expr, __FILE__, __LINE__) == IDCANCEL) \
::DebugBreak(); \
} while (0)
#endif
// Version of _ASSERTE usable within inline functions
// i.e. Does not have do/while construct that is not allowed in inline functions currently
//
#if !defined(_ASSERTE_)
#define _ASSERTE_(expr) ((expr) ? (0) : DebugHlpr_ASSERTE(#expr, __FILE__, __LINE__))
#endif
template <class T>
void __cdecl TDebugHlpr<T>::TRACE_HLPR(T* szFormat, ...)
{
va_list args;
va_start(args, szFormat);
int bufSize;
TCHAR szBuffer[_MAX_PATH*2];
bufSize = wvsprintf(szBuffer, szFormat, args);
_ASSERTE(bufSize < sizeof(szBuffer));
::OutputDebugString(szBuffer);
va_end(args);
}
// Template to 'hide' some functions for string conversions
//
template <class T = TCHAR>
class TStringConverter
{
public:
static LPSTR WideToAnsi(LPCWSTR src);
static LPWSTR AnsiToWide(LPCSTR src);
static LPWSTR AnsiToOLESTR(LPCSTR src);
static LPWSTR WideToOLESTR(LPCWSTR src);
static TCHAR* strnewdup(const T* src);
};
// String Helper conversion routines
// NOTE: Return value must be deleted[]
//
template <class T> LPSTR
TStringConverter<T>::WideToAnsi(LPCWSTR src)
{
int size = ::WideCharToMultiByte(CP_ACP, 0, src, -1, 0, 0, 0, 0);
LPSTR dst = new char[size];
size = ::WideCharToMultiByte(CP_ACP, 0, src, -1, dst, size, 0, 0);
_ASSERTE(size != 0);
return dst;
}
// NOTE: Return value must be passed to '::SysFreeString'
//
template <class T> OLECHAR*
TStringConverter<T>::AnsiToOLESTR(LPCSTR src)
{
int size = ::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, src, -1, 0, 0);
LPWSTR dst = ::SysAllocStringLen(0, size);
size = ::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, src, -1, dst, size);
_ASSERTE(size != 0);
return dst;
}
// NOTE: Return value must be deleted[]
//
template <class T> LPWSTR
TStringConverter<T>::AnsiToWide(LPCSTR src)
{
int size = ::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, src, -1, 0, 0);
LPWSTR dst = new wchar_t[size];
size = ::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, src, -1, dst, size);
_ASSERTE(size != 0);
return dst;
}
// NOTE: Return value must be passed to '::SysFreeString'
//
template <class T> OLECHAR*
TStringConverter<T>::WideToOLESTR(LPCWSTR src)
{
return ::SysAllocString(src);
}
// NOTE: Return value must be deleted[]
//
template <class T> TCHAR*
TStringConverter<T>::strnewdup(const T* str)
{
_ASSERTE(str);
return lstrcpy(new TCHAR[lstrlen(str)+1], str);
}
// Return value must be deleted[]
//
inline LPSTR WideToAnsi(LPCWSTR src)
{
return TStringConverter<TCHAR>::WideToAnsi(src);
}
// NOTE: Return value must be passed to '::SysFreeString'
//
inline OLECHAR* AnsiToOLESTR(LPCSTR src)
{
return TStringConverter<TCHAR>::AnsiToOLESTR(src);
}
// NOTE: Return value must be '::SysFreeString'
//
inline OLECHAR* WideToOLESTR(LPCWSTR src)
{
return TStringConverter<TCHAR>::WideToOLESTR(src);
}
// NOTE: Return value must be delete[]
//
inline TCHAR* strnewdup(LPCTSTR str)
{
_ASSERTE_(str);
return TStringConverter<TCHAR>::strnewdup(str);
}
// Wrapper for freeing BSTRs
//
class TOleString
{
public:
TOleString(BSTR bstr) : m_bstr(bstr) {}
TOleString(const CHAR *str) : m_bstr(str ? AnsiToOLESTR(str) : 0) {}
~TOleString() { ::SysFreeString(m_bstr); }
operator BSTR() const { return m_bstr;}
protected:
BSTR m_bstr;
};
// Cheap coder's quick buffer wrapper...
//
template <int LEN>
class TCharBuff
{
public:
TCharBuff() : m_Data(new TCHAR[LEN]) { m_Data[0] = 0; }
TCharBuff(LPCTSTR src) : m_Data(new TCHAR[LEN]) { *this = src; }
TCharBuff(const TCharBuff& src) { *this = src; }
~TCharBuff() { delete[] m_Data; }
operator LPCTSTR() const { return m_Data; }
int Len() const { return LEN; }
bool operator !() const { return m_Data[0]==0;}
LPTSTR Copy(LPCTSTR src) { return lstrcpyn(m_Data, src, LEN); }
LPTSTR Cat (LPCTSTR src) { return lstrcat(m_Data, src); }
TCharBuff& operator =(LPCTSTR src) { Copy(src); return *this; }
TCharBuff& operator =(const TCharBuff& src) { Copy(src); return *this; }
TCharBuff& operator+=(LPCTSTR src) { Cat(src); return *this; }
protected:
LPTSTR m_Data;
};
// TPtrBase
// Base class for automation pointer management. Provides basic implementation for
// smart pointer object.
//
template<class T>
class TPtrBase
{
public:
// Methods implementing pointer semantics
//
T& operator * () const { _ASSERTE_(m_ptr); return *m_ptr; }
operator T* () const { return m_ptr;}
bool operator !() const { return m_ptr == 0; }
T* operator->() const { _ASSERTE_(m_ptr); return m_ptr; }
T** operator &() /*const*/ { return &m_ptr; }
// Comparison operators
//
bool operator == (T *rhs) const { return m_ptr == rhs;}
bool operator == (const TPtrBase<T> &rhs) const { return m_ptr == rhs.m_ptr; }
bool operator != (T *rhs) const { return m_ptr != rhs;}
bool operator != (const TPtrBase<T> &rhs) const { return m_ptr != rhs.m_ptr; }
protected:
TPtrBase() : m_ptr(0) {}
TPtrBase(T* p) : m_ptr(p) {}
T* get () const { return m_ptr; }
T* release () { return reset(0); }
T* reset (T* p = 0) { T* tmp = m_ptr; m_ptr = p; return tmp; }
// Actual data
//
T* m_ptr;
private:
// Prevent new/delete
//
void* operator new(size_t);
void operator delete(void*/*p*/){/*::delete p;*/};
};
// TPtr: Smart pointer object for non-array pointers
//
template<class T>
class TPtr : public TPtrBase<T>
{
public:
TPtr() : TPtrBase<T>() {}
TPtr(T* src) : TPtrBase<T>(src) {}
TPtr(TPtr<T>& src) : TPtrBase<T>(src.release()) {}
~TPtr() {clear(0);}
// Assignment operators
//
TPtr& operator = (TPtr<T>& src)
{
// Transfer ownership of pointer to receiver
//
reset(src.release());
return *this;
}
TPtr& operator = (T* src)
{
clear(src);
return *this;
}
T* operator& () const
{
return get();
}
// Clear object - free pointer
//
void clear(T *src)
{
if (m_ptr)
delete m_ptr;
m_ptr = src;
}
};
// TAPtr: Smart pointer object for array new'ed memory
//
template<class T>
class TAPtr : public TPtrBase<T>
{
public:
TAPtr() : TPtrBase<T>() {}
TAPtr(T src[]) : TPtrBase<T>(src) {}
TAPtr(TPtr<T>& src) : TPtrBase<T>(src.release()) {}
~TAPtr() {clear(0);}
// Assignment operators
//
TAPtr& operator = (TAPtr<T>& src)
{
// Transfer ownership of pointer to receiver
//
reset(src.release());
return *this;
}
TAPtr& operator = (T src[])
{
clear(src);
return *this;
}
// Subscript operator (for array)
//
T& operator [](int i) const
{
_ASSERTE_(m_ptr);
return m_ptr[i];
}
// Clear object - free pointer
//
void clear(T src[])
{
if (m_ptr)
delete []m_ptr;
m_ptr = src;
}
};
// Wrapper class encapsulating a DLL
//
class TDll
{
public:
TDll(LPCTSTR name) : m_Hinstance(::LoadLibrary(name)) {}
~TDll()
{
if (m_Hinstance)
::FreeLibrary(m_Hinstance);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -