📄 utilcls.h
字号:
}
operator HINSTANCE() const { return m_Hinstance; }
FARPROC GetProcAddress(LPCSTR funcName) const { return ::GetProcAddress(*this, funcName); }
protected:
HINSTANCE m_Hinstance;
private:
TDll(const TDll&);
TDll& operator=(const TDll&);
};
// TDllProc: Encapsulates a DLL EntryPoint/FARPROC
//
class TDllProc
{
public:
TDllProc(const TDll& dll, LPCSTR funcName)
{
m_Proc = dll.GetProcAddress(funcName);
}
operator bool() { return m_Proc != 0; }
protected:
FARPROC m_Proc;
};
// FARPROC that's CDECL, returns HRESULT and takes one parameter
//
template <class P1>
class TDllProc1 : public TDllProc
{
public:
TDllProc1(const TDll& dll , LPCTSTR funcName) : TDllProc(dll, funcName) {};
HRESULT operator ()(P1 erste)
{
typedef HRESULT (__cdecl* outproc)(P1 erste);
return ((outproc)m_Proc)(erste);
}
};
// FARPROC that's STDCALL, returns HRESULT and take two parameters
//
template <class P1, class P2>
class TDllStdProc2 : public TDllProc
{
public:
TDllStdProc2(const TDll& dll, LPCTSTR funcName) : TDllProc(dll, funcName) {}
HRESULT operator () (P1 p1, P2 p2)
{
typedef HRESULT (__stdcall* outproc)(P1 p1, P2 p2);
return ((outproc)m_Proc)(p1, p2);
}
};
// TInitOle: Simple object to initialize and unintialize Ole in a safe fashion
//
template <class T>
class TInitOleT
{
public:
TInitOleT(COINIT initFlag = m_DefaultInitFlag)
{
// Avoid CoInitializeEx wherever possible - It's not available on shipping WIN95
#if defined(_ATL_COINIT_MULTITHREADED)
HRESULT hr_Initializing_OLE = ::CoInitializeEx(0, initFlag);
#else
_ASSERTE_((initFlag & COINIT_MULTITHREADED) == 0 /* User requested MT but macro was not properly defined */);
HRESULT hr_Initializing_OLE = ::CoInitialize(0);
#endif
/* OLECHECK(hr_Initializing_OLE); */
init = SUCCEEDED(hr_Initializing_OLE);
}
~TInitOleT()
{
if (init)
::CoUninitialize();
}
// Methods to test whether initialization was succcessful
//
operator bool () const { return init; }
int operator ! () const { return init == false; }
// static members
//
static COINIT m_DefaultInitFlag;
static void Init();
protected:
// Flags if initialization was successful
//
bool init;
private:
// Prevent accidental copy to ensure equal numbers of Init/UnInit
//
TInitOleT(const TInitOleT<T>&);
TInitOleT<T>& operator = (const TInitOleT<T>&);
};
// Default flag when initializing OLE
//
#if !defined(_ATL_COINIT_MULTITHREADED)
template <class T> COINIT
TInitOleT<T>::m_DefaultInitFlag = COINIT_APARTMENTTHREADED;
#else
template <class T> COINIT
TInitOleT<T>::m_DefaultInitFlag = COINIT_MULTITHREADED;
#endif
// Creates a single instance that initializes OLE
//
template <class T> void
TInitOleT<T>::Init()
{
static TInitOleT<T> instance(m_DefaultInitFlag);
}
// TInitOle is backward compatible with v3.0's TInitOle
//
typedef TInitOleT</*Pick a type*/int> TInitOle;
// Helper class used to create Default Interface Wrapper of CoClasses
// (Used by Code generated by TLIBIMP)
//
class CoClassCreator
{
public:
// Enhanced version of CoCreateInstance that handles failure due to CLSCTX_REMOTESERVER Flag
//
static HRESULT CoCreateInstance(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
{
// Make sure OLE's initialized
//
TInitOle::Init();
HRESULT hr;
// Define NO_REMOTE_BINDING if you do not want to try to bind to a remote server
// (With some setups the remote request is not handled gracefully!?!)
#if !defined(NO_REMOTE_BINDING)
hr = ::CoCreateInstance(rclsid, 0, CLSCTX_SERVER, riid, ppv);
// If succeeded, or failed for reasons other than invalid arguments
//
if (SUCCEEDED(hr) || hr != E_INVALIDARG)
return hr;
#endif
// Call CoCreateInstance, this time masking off CLSCTX_REMOTE_SERVER
//
hr = ::CoCreateInstance(rclsid, 0, CLSCTX_SERVER & ~CLSCTX_REMOTE_SERVER, riid, ppv);
return hr;
}
// Template function to handle Remote Creation
//
template <class INTF>
static HRESULT CreateRemote(LPCWSTR machineName, REFCLSID rclsid, REFIID riid, INTF **ppv)
{
// Make sure OLE's initialized
//
TInitOle::Init();
COSERVERINFO serverInfo = {0, const_cast<LPWSTR>(machineName), 0, 0};
MULTI_QI mqi = {&riid, 0, 0};
HRESULT hr = ::CoCreateInstanceEx(rclsid, 0,
CLSCTX_REMOTE_SERVER,
&serverInfo, 1, &mqi);
if (SUCCEEDED(hr))
*ppv = (INTF*)mqi.pItf;
return hr;
}
};
// VARIANT_BOOL is really just a short. Therefore it's not distinguishable from a
// VT_I2. Most servers will take VT_I2 in a VARIANT when expecting a BOOLEAN.
// However, some (such as Excel97) won't. So to distinguish, we'll expose VT_BOOL
// as TOLEBOOL instead of VARIANT_BOOL.
//
// (The main issue is sizeof(WORD) != sizeof(bool) - hence VT_BOOL|VT_BYREF would
// break if we used C++ bool type for OLE VT_BOOL parameters.)
//
class TOLEBOOL
{
public:
TOLEBOOL(bool flag = false) : m_VariantBool(flag ? VARIANT_TRUE : VARIANT_FALSE) {}
TOLEBOOL(VARIANT_BOOL flag) : m_VariantBool(flag ? VARIANT_TRUE : VARIANT_FALSE) {}
TOLEBOOL(int flag) : m_VariantBool(flag ? VARIANT_TRUE : VARIANT_FALSE) {}
TOLEBOOL(const TOLEBOOL& src) : m_VariantBool(src.m_VariantBool) {}
TOLEBOOL& operator=(const TOLEBOOL& src)
{
m_VariantBool = src.m_VariantBool;
return *this;
}
TOLEBOOL& operator=(bool flag)
{
m_VariantBool = flag ? VARIANT_TRUE : VARIANT_FALSE;
return *this;
}
TOLEBOOL& operator=(VARIANT_BOOL flag)
{
m_VariantBool = flag ? VARIANT_TRUE : VARIANT_FALSE;
return *this;
}
TOLEBOOL& operator=(int flag)
{
m_VariantBool = flag ? VARIANT_TRUE : VARIANT_FALSE;
return *this;
}
bool operator==(bool val) { return val ? (m_VariantBool != VARIANT_FALSE) : (m_VariantBool == VARIANT_FALSE); }
bool operator==(VARIANT_BOOL val) { return m_VariantBool == val; }
operator bool () const { return m_VariantBool != VARIANT_FALSE; }
operator VARIANT_BOOL () const { return (m_VariantBool != VARIANT_FALSE) ? VARIANT_TRUE : VARIANT_FALSE; }
protected:
VARIANT_BOOL m_VariantBool;
};
///////////////////////////////////////////////////////////////////////////////
// The following macros utilize the Variant access macros defined in OLEAUTO.H
// to set the VARTYPE (vt) and the related variable at once. For example:
//
// V_TYPE_VAR(CY, amount) expands to vt = VT_CY;
// V_CY(this) = amount;
///////////////////////////////////////////////////////////////////////////////
#if !defined(SET_VTYPE_AND_VAR)
#define SET_VTYPE_AND_VAR(type, val) vt = VT_ ## type ; \
V_ ## type (this) = val;
#endif
#if !defined(SET_VTYPE_AND_VARREF)
#define SET_VTYPE_AND_VARREF(type, val) vt = VT_ ## type | VT_BYREF; \
V_ ## type ## REF (this) = val;
#endif
///////////////////////////////////////////////////////////////////////////////
// TVariantT
// ========
// Templatized VARIANT support. T must be a VARIANT or VARIANT-derived type
///////////////////////////////////////////////////////////////////////////////
template <class T>
class TVariantT : public T
{
public:
TVariantT()
{
::VariantInit(this);
}
~TVariantT()
{
::VariantClear(this);
}
TVariantT(const TVariantT& src)
{
::VariantInit(this);
::VariantCopy(this, (VARIANT*)&src);
}
// Ctr - From basic C++ types
TVariantT(bool src)
{
::VariantInit(this);
SET_VTYPE_AND_VAR(BOOL, src ? VARIANT_TRUE : VARIANT_FALSE);
}
TVariantT(const TOLEBOOL& src)
{
::VariantInit(this);
SET_VTYPE_AND_VAR(BOOL, src ? VARIANT_TRUE : VARIANT_FALSE);
}
TVariantT(char src)
{
::VariantInit(this);
SET_VTYPE_AND_VAR(I1, src);
}
TVariantT(signed char src)
{
::VariantInit(this);
SET_VTYPE_AND_VAR(I1, src);
}
TVariantT(unsigned char src)
{
::VariantInit(this);
SET_VTYPE_AND_VAR(UI1, src);
}
TVariantT(short src)
{
::VariantInit(this);
SET_VTYPE_AND_VAR(I2, src);
}
TVariantT(unsigned short src, bool isBoolean = false)
{
::VariantInit(this);
if (isBoolean)
{
SET_VTYPE_AND_VAR(BOOL, src);
}
else
{
SET_VTYPE_AND_VAR(UI2, src);
}
}
TVariantT(int src)
{
::VariantInit(this);
SET_VTYPE_AND_VAR(I4, src);
}
TVariantT(unsigned int src)
{
::VariantInit(this);
SET_VTYPE_AND_VAR(UI4, src);
}
TVariantT(long src, bool isError = false)
{
::VariantInit(this);
if (isError)
{
SET_VTYPE_AND_VAR(ERROR, src);
}
else
{
SET_VTYPE_AND_VAR(I4, src);
}
}
TVariantT(unsigned long src)
{
::VariantInit(this);
SET_VTYPE_AND_VAR(UI4, src);
}
TVariantT(float src)
{
::VariantInit(this);
SET_VTYPE_AND_VAR(R4, src);
}
TVariantT(double src, bool isDate = false)
{
::VariantInit(this);
if (isDate)
{
SET_VTYPE_AND_VAR(DATE, src);
}
else
{
SET_VTYPE_AND_VAR(R8, src);
}
}
TVariantT(long double src)
{
::VariantInit(this);
SET_VTYPE_AND_VAR(R8, double(src));
}
// Ctr - From OLE structures
TVariantT(const CURRENCY& src)
{
::VariantInit(this);
SET_VTYPE_AND_VAR(CY, src);
}
TVariantT(SAFEARRAY& src)
{
::VariantInit(this);
SetSAFEARRAY(&src);
}
TVariantT(SAFEARRAY* src)
{
::VariantInit(this);
SetSAFEARRAY(src);
}
TVariantT(const VARIANT& src)
{
::VariantInit(this);
::VariantCopy(this, const_cast<VARIANTARG*>(&src));
}
TVariantT(VARIANT* src)
{
::VariantInit(this);
::VariantCopy(this, src);
}
// Ctr - From VCL utility classes (Members are exposed only of VCL headers have been included)
//
#if defined(SYSVARI_H)
TVariantT(const System::Variant& rhs)
{
::VariantInit(this);
*this = rhs;
}
#endif
#if defined(DSTRING_H)
TVariantT(const AnsiString& src)
{
::VariantInit(this);
*this = src.c_str();
}
#endif
#if defined(SYSCURR_H)
TVariantT(const Currency& src)
{
::VariantInit(this);
SET_VTYPE_AND_VAR(CY, *(reinterpret_cast<tagCY*>(&(const_cast<Currency&>(src).Val))))
}
TVariantT(Currency* src)
{
::VariantInit(this);
SET_VTYPE_AND_VARREF(CY, reinterpret_cast<tagCY*>(&(src->Val)));
}
#endif
#if defined(SYSTDATE_H)
TVariantT(const TDateTime& src)
{
::VariantInit(this);
SET_VTYPE_AND_VAR(DATE, src);
}
TVariantT(TDateTime* src)
{
::VariantInit(this);
SET_VTYPE_AND_VARREF(DATE, reinterpret_cast<DATE*>(src));
}
#endif
#if defined(WSTRING_H)
TVariantT(const WideString& src)
{
::VariantInit(this);
SET_VTYPE_AND_VAR(BSTR, src.Copy());
}
#endif
#if defined(SYSTOBJ_H)
// Ref-counted Dispatch interface object
TVariantT(const System::DelphiInterface<IDispatch>& src)
{
::VariantInit(this);
if (!!src)
src->AddRef();
SET_VTYPE_AND_VAR(DISPATCH, src);
}
#endif
// Asciiz pointer
TVariantT(const char* src) // Treated as pointer Asciiz string
{
::VariantInit(this);
int size = ::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, src, -1, 0, 0);
LPWSTR dst = ::SysAllocStringLen(0, size);
::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, src, -1, dst, size);
SET_VTYPE_AND_VAR(BSTR, dst);
}
// Ctr - OLE ptrs
// Set isSysString to False if TVariantT must allocate a copy of the WCHAR* passed in.
// Otherwise, this constructor assumes that the WCHAR* was allocated via 'SysAlloc...'
// and it takes ownership of the pointer.
TVariantT(wchar_t* src, bool isSysString = true) // BSTR support
{
::VariantInit(this);
SET_VTYPE_AND_VAR(BSTR, isSysString ? src : ::SysAllocString(src));
}
TVariantT(IUnknown* src)
{
::VariantInit(this);
if (src)
src->AddRef();
SET_VTYPE_AND_VAR(UNKNOWN, src);
}
TVariantT(IDispatch* src)
{
::VariantInit(this);
if (src)
src->AddRef();
SET_VTYPE_AND_VAR(DISPATCH, src);
}
//By ref constructors
// NOTE: We cannot take a bool* since the sizes of VARIANT_BOOL and bool
// differ. Instead we'll take a TOLEBOOL. Taking a VARIANT_BOOL*
// is not distinguishable from a short pointer.
//
TVariantT(TOLEBOOL* src)
{
::VariantInit(this);
SET_VTYPE_AND_VARREF(BOOL, src);
}
TVariantT(signed char* src)
{
::VariantInit(this);
SET_VTYPE_AND_VARREF(I1, src);
}
TVariantT(unsigned char* src)
{
::VariantInit(this);
SET_VTYPE_AND_VARREF(UI1, src);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -