diff options
Diffstat (limited to 'CPP/Windows/PropVariant.cpp')
-rw-r--r--[-rwxr-xr-x] | CPP/Windows/PropVariant.cpp | 83 |
1 files changed, 70 insertions, 13 deletions
diff --git a/CPP/Windows/PropVariant.cpp b/CPP/Windows/PropVariant.cpp index 90212e08..caa4c319 100755..100644 --- a/CPP/Windows/PropVariant.cpp +++ b/CPP/Windows/PropVariant.cpp @@ -2,13 +2,43 @@ #include "StdAfx.h" -#include "PropVariant.h" - #include "../Common/Defs.h" +#include "PropVariant.h" + namespace NWindows { namespace NCOM { +HRESULT PropVarEm_Alloc_Bstr(PROPVARIANT *p, unsigned numChars) +{ + p->bstrVal = ::SysAllocStringLen(0, numChars); + if (!p->bstrVal) + { + p->vt = VT_ERROR; + p->scode = E_OUTOFMEMORY; + return E_OUTOFMEMORY; + } + p->vt = VT_BSTR; + return S_OK; +} + +HRESULT PropVarEm_Set_Str(PROPVARIANT *p, const char *s) +{ + UINT len = (UINT)strlen(s); + p->bstrVal = ::SysAllocStringByteLen(0, (UINT)len * sizeof(OLECHAR)); + if (!p->bstrVal) + { + p->vt = VT_ERROR; + p->scode = E_OUTOFMEMORY; + return E_OUTOFMEMORY; + } + p->vt = VT_BSTR; + BSTR dest = p->bstrVal; + for (UINT i = 0; i <= len; i++) + dest[i] = s[i]; + return S_OK; +} + CPropVariant::CPropVariant(const PROPVARIANT &varSrc) { vt = VT_EMPTY; @@ -67,7 +97,6 @@ CPropVariant& CPropVariant::operator=(LPCOLESTR lpszSrc) return *this; } - CPropVariant& CPropVariant::operator=(const char *s) { InternalClear(); @@ -100,22 +129,40 @@ CPropVariant& CPropVariant::operator=(bool bSrc) return *this; } +BSTR CPropVariant::AllocBstr(unsigned numChars) +{ + if (vt != VT_EMPTY) + InternalClear(); + vt = VT_BSTR; + wReserved1 = 0; + bstrVal = ::SysAllocStringLen(0, numChars); + if (bstrVal == NULL) + { + throw kMemException; + // vt = VT_ERROR; + // scode = E_OUTOFMEMORY; + } + return bstrVal; +} + #define SET_PROP_FUNC(type, id, dest) \ CPropVariant& CPropVariant::operator=(type value) \ { if (vt != id) { InternalClear(); vt = id; } \ dest = value; return *this; } SET_PROP_FUNC(Byte, VT_UI1, bVal) -SET_PROP_FUNC(Int16, VT_I2, iVal) +// SET_PROP_FUNC(Int16, VT_I2, iVal) SET_PROP_FUNC(Int32, VT_I4, lVal) SET_PROP_FUNC(UInt32, VT_UI4, ulVal) SET_PROP_FUNC(UInt64, VT_UI8, uhVal.QuadPart) +SET_PROP_FUNC(Int64, VT_I8, hVal.QuadPart) SET_PROP_FUNC(const FILETIME &, VT_FILETIME, filetime) -static HRESULT MyPropVariantClear(PROPVARIANT *prop) +HRESULT PropVariant_Clear(PROPVARIANT *prop) throw() { - switch(prop->vt) + switch (prop->vt) { + case VT_EMPTY: case VT_UI1: case VT_I1: case VT_I2: @@ -134,14 +181,21 @@ static HRESULT MyPropVariantClear(PROPVARIANT *prop) case VT_DATE: prop->vt = VT_EMPTY; prop->wReserved1 = 0; + prop->wReserved2 = 0; + prop->wReserved3 = 0; + prop->uhVal.QuadPart = 0; return S_OK; } return ::VariantClear((VARIANTARG *)prop); + // return ::PropVariantClear(prop); + // PropVariantClear can clear VT_BLOB. } HRESULT CPropVariant::Clear() { - return MyPropVariantClear(this); + if (vt == VT_EMPTY) + return S_OK; + return PropVariant_Clear(this); } HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc) @@ -184,9 +238,12 @@ HRESULT CPropVariant::Attach(PROPVARIANT *pSrc) HRESULT CPropVariant::Detach(PROPVARIANT *pDest) { - HRESULT hr = MyPropVariantClear(pDest); - if (FAILED(hr)) - return hr; + if (pDest->vt != VT_EMPTY) + { + HRESULT hr = PropVariant_Clear(pDest); + if (FAILED(hr)) + return hr; + } memcpy(pDest, this, sizeof(PROPVARIANT)); vt = VT_EMPTY; return S_OK; @@ -194,6 +251,8 @@ HRESULT CPropVariant::Detach(PROPVARIANT *pDest) HRESULT CPropVariant::InternalClear() { + if (vt == VT_EMPTY) + return S_OK; HRESULT hr = Clear(); if (FAILED(hr)) { @@ -233,9 +292,7 @@ int CPropVariant::Compare(const CPropVariant &a) case VT_UI8: return MyCompare(uhVal.QuadPart, a.uhVal.QuadPart); case VT_BOOL: return -MyCompare(boolVal, a.boolVal); case VT_FILETIME: return ::CompareFileTime(&filetime, &a.filetime); - case VT_BSTR: - return 0; // Not implemented - // return MyCompare(aPropVarint.cVal); + case VT_BSTR: return 0; // Not implemented default: return 0; } } |