Gray C++ Libraries  0.0.2
A set of C++ libraries for MSVC, GNU on Windows, WinCE, Linux
cWinVariant.h
Go to the documentation of this file.
1 //
5 //
6 
7 #ifndef _INC_cWinVariant_H
8 #define _INC_cWinVariant_H
9 #ifndef NO_PRAGMA_ONCE
10 #pragma once
11 #endif
12 
13 #include "cWinString.h"
14 
15 #if defined(_WIN32)
17 #include "GrayCore/include/cValT.h"
18 #include "GrayCore/include/cMem.h"
20 
21 namespace GrayLib
22 {
23  UNITTEST2_PREDEF(cWinVariant);
24 
25  class GRAYLIB_LINK cWinVariant
26 #if defined(_MFC_VER) // using MFC.
27  : public CComVariant
28 #else
29  : public tagVARIANT
30 #endif
31  {
36 
37  public:
38 #if defined(_MFC_VER) // using MFC.
39  cWinVariant()
40  {
41  }
42  cWinVariant(enum VARENUM vtSrc)
43  {
44  this->vt = vtSrc;
45  }
46  cWinVariant(int nSrc, enum VARENUM vtSrc = VT_I4)
47  : CComVariant(nSrc,vtSrc)
48  {
49  }
50 
51 #else
52  cWinVariant() throw()
53  {
54  // vt = VT_EMPTY is faster than ::VariantInit(this);
55  cMem::Zero(this, sizeof(*this));
56  }
57  ~cWinVariant() throw()
58  {
59  Clear();
60  }
61  cWinVariant(enum VARENUM vtinit)
62  {
64  cMem::Zero(this, sizeof(*this));
65  // V_VT(this) = vtinit;
66  vt = (VARTYPE)vtinit;
67  }
68 
69  cWinVariant(const VARIANT& varSrc)
70  {
71  vt = VT_EMPTY;
72  InternalCopy(&varSrc);
73  }
74  cWinVariant(const cWinVariant& varSrc)
75  {
76  vt = VT_EMPTY;
77  InternalCopy(&varSrc);
78  }
79  cWinVariant(VARIANT* pvarSrc)
80  {
81  vt = VT_EMPTY;
82  *this = pvarSrc;
83  }
84  cWinVariant(LPCOLESTR lpszSrc)
85  {
86  vt = VT_EMPTY;
87  *this = lpszSrc;
88  }
89  cWinVariant(const char* lpszSrc)
90  {
91  vt = VT_EMPTY;
92  *this = lpszSrc;
93  }
94  cWinVariant(bool bSrc)
95  {
96  vt = VT_BOOL;
97  boolVal = bSrc ? VARIANT_TRUE : VARIANT_FALSE;
98  }
99  cWinVariant(int nSrc, VARTYPE vtSrc = VT_I4) throw()
100  {
101  ASSERT(vtSrc == VT_I4 || vtSrc == VT_INT);
102  vt = vtSrc;
103  intVal = nSrc;
104  }
105  cWinVariant(BYTE nSrc) throw()
106  {
107  vt = VT_UI1;
108  bVal = nSrc;
109  }
110  cWinVariant(short nSrc) throw()
111  {
112  vt = VT_I2;
113  iVal = nSrc;
114  }
115  cWinVariant(long nSrc, VARTYPE vtSrc = VT_I4) throw()
116  {
117  ASSERT(vtSrc == VT_I4 || vtSrc == VT_ERROR);
118  vt = vtSrc;
119  lVal = nSrc;
120  }
121  cWinVariant(float fltSrc) throw()
122  {
123  vt = VT_R4;
124  fltVal = fltSrc;
125  }
126  cWinVariant(double dblSrc, VARTYPE vtSrc = VT_R8) throw()
127  {
128  ASSERT(vtSrc == VT_R8 || vtSrc == VT_DATE);
129  vt = vtSrc;
130  dblVal = dblSrc;
131  }
132 #if !defined(UNDER_CE) && (defined(USE_64BIT) || (_WIN32_WINNT >= 0x0501) || defined(_ATL_SUPPORT_VT_I8))
133  cWinVariant(LONGLONG nSrc) throw()
134  {
135  vt = VT_I8;
136  llVal = nSrc;
137  }
138  cWinVariant(ULONGLONG nSrc) throw()
139  {
140  vt = VT_UI8;
141  ullVal = nSrc;
142  }
143 #endif
144  cWinVariant(CY cySrc) throw()
145  {
146  // money/currency
147  vt = VT_CY;
148  cyVal.Hi = cySrc.Hi;
149  cyVal.Lo = cySrc.Lo;
150  }
151  cWinVariant(IDispatch* pSrc) throw()
152  {
153  vt = VT_DISPATCH;
154  pdispVal = pSrc;
155  // Need to AddRef as VariantClear will Release
156  if (pdispVal != nullptr)
157  pdispVal->AddRef();
158  }
159  cWinVariant(IUnknown* pSrc) throw()
160  {
161  // cIUnkPtr<>
162  vt = VT_UNKNOWN;
163  punkVal = pSrc;
164  // Need to AddRef as VariantClear will Release
165  if (punkVal != nullptr)
166  punkVal->AddRef();
167  }
168  cWinVariant(char cSrc) throw()
169  {
170  vt = VT_I1;
171  cVal = cSrc;
172  }
173  cWinVariant(unsigned short nSrc) throw()
174  {
175  vt = VT_UI2;
176  uiVal = nSrc;
177  }
178  cWinVariant(unsigned long nSrc) throw()
179  {
180  vt = VT_UI4;
181  ulVal = nSrc;
182  }
183  cWinVariant(unsigned int nSrc, VARTYPE vtSrc = VT_UI4) throw()
184  {
185  ASSERT(vtSrc == VT_UI4 || vtSrc == VT_UINT);
186  vt = vtSrc;
187  uintVal = nSrc;
188  }
189  cWinVariant(const CComBSTR& bstrSrc)
190  {
191  vt = VT_EMPTY;
192  *this = bstrSrc;
193  }
194 
195 #ifndef UNDER_CE
196  cWinVariant(const SAFEARRAY *pSrc)
197  {
198  if (pSrc == nullptr)
199  {
200  // vt = VT_EMPTY;
201  cMem::Zero(this, sizeof(*this));
202  return;
203  }
204  InternalSafeArray(pSrc);
205  }
206 #endif
207 
208  protected:
209  void InitTypeInt(enum VARENUM vtinit)
210  {
212  if (vtinit == vt)
213  return;
214  Clear();
215  vt = (VARTYPE)vtinit; // V_VT(this) = vtinit;
216  }
217 
218  public:
219  void InitType(enum VARENUM vtinit)
220  {
223  Clear();
224  cMem::Zero(this, sizeof(*this));
225  vt = (VARTYPE)vtinit; // V_VT(this) = vtinit;
226  }
227 
228  // Assignment Operators
229  public:
230  const cWinVariant& operator=(const cWinVariant& varSrc)
231  {
232  InternalCopy(&varSrc);
233  return *this;
234  }
235  const cWinVariant& operator=(const VARIANT& varSrc)
236  {
237  InternalCopy(&varSrc);
238  return *this;
239  }
240 
241  const cWinVariant& operator=(const CComBSTR& bstrSrc)
242  {
243  InitType(VT_BSTR);
244  bstrVal = bstrSrc.Copy();
245  if (bstrVal == nullptr && bstrSrc.m_str != nullptr)
246  {
247  vt = VT_ERROR;
248  scode = E_OUTOFMEMORY;
249  }
250  return *this;
251  }
252 
253  const cWinVariant& operator=(LPCOLESTR lpszSrc)
254  {
255  // wchar_t* for UNICODE
256  InitType(VT_BSTR);
257  bstrVal = ::SysAllocString(lpszSrc);
258 
259  if (bstrVal == nullptr && lpszSrc != nullptr)
260  {
261  vt = VT_ERROR;
262  scode = E_OUTOFMEMORY;
263  }
264  return *this;
265  }
266 
267  const cWinVariant& operator=(const char* lpszSrc)
268  {
269  // USES_CONVERSION_EX;
270  // char*
271  InitType(VT_BSTR);
272  cWinString strTmp(lpszSrc);
273  this->bstrVal = strTmp.Detach();
274 
275  if (bstrVal == nullptr && lpszSrc != nullptr)
276  {
277  vt = VT_ERROR;
278  scode = E_OUTOFMEMORY;
279  }
280  return *this;
281  }
282 
283  const cWinVariant& operator=(bool bSrc)
284  {
285  InitTypeInt(VT_BOOL);
286  boolVal = bSrc ? VARIANT_TRUE : VARIANT_FALSE;
287  return *this;
288  }
289 
290  const cWinVariant& operator=(int nSrc) throw()
291  {
292  InitTypeInt(VT_I4);
293  intVal = nSrc;
294  return *this;
295  }
296 
297  const cWinVariant& operator=(BYTE nSrc) throw()
298  {
299  InitTypeInt(VT_UI1);
300  bVal = nSrc;
301  return *this;
302  }
303 
304  const cWinVariant& operator=(short nSrc) throw()
305  {
306  InitTypeInt(VT_I2);
307  iVal = nSrc;
308  return *this;
309  }
310 
311  const cWinVariant& operator=(long nSrc) throw()
312  {
313  InitTypeInt(VT_I4);
314  lVal = nSrc;
315  return *this;
316  }
317 
318  const cWinVariant& operator=(float fltSrc) throw()
319  {
320  InitTypeInt(VT_R4);
321  fltVal = fltSrc;
322  return *this;
323  }
324 
325  const cWinVariant& operator=(double dblSrc) throw()
326  {
327  InitTypeInt(VT_R8);
328  dblVal = dblSrc;
329  return *this;
330  }
331 
332  const cWinVariant& operator=(CY cySrc) throw()
333  {
334  InitTypeInt(VT_CY);
335  cyVal.Hi = cySrc.Hi;
336  cyVal.Lo = cySrc.Lo;
337  return *this;
338  }
339 
340  const cWinVariant& operator=(IDispatch* pSrc) throw()
341  {
342  InitType(VT_DISPATCH);
343  pdispVal = pSrc;
344  // Need to AddRef as VariantClear will Release
345  if (pdispVal != nullptr)
346  pdispVal->AddRef();
347  return *this;
348  }
349 
350  const cWinVariant& operator=(IUnknown* pSrc) throw()
351  {
352  InitType(VT_UNKNOWN);
353  punkVal = pSrc;
354 
355  // Need to AddRef as VariantClear will Release
356  if (punkVal != nullptr)
357  punkVal->AddRef();
358  return *this;
359  }
360 
361  const cWinVariant& operator=(VARIANT* ppSrc)
362  {
363  InitType((VARENUM)(VT_VARIANT | VT_BYREF));
364  pvarVal = ppSrc;
365  return *this;
366  }
367 
368  const cWinVariant& operator=(char cSrc) throw()
369  {
370  InitTypeInt(VT_I1);
371  cVal = cSrc;
372  return *this;
373  }
374 
375  const cWinVariant& operator=(unsigned short nSrc) throw()
376  {
377  InitTypeInt(VT_UI2);
378  uiVal = nSrc;
379  return *this;
380  }
381 
382  const cWinVariant& operator=(unsigned long nSrc) throw()
383  {
384  InitTypeInt(VT_UI4);
385  ulVal = nSrc;
386  return *this;
387  }
388 
389  const cWinVariant& operator=(unsigned int nSrc) throw()
390  {
391  InitTypeInt(VT_UI4);
392  uintVal = nSrc;
393  return *this;
394  }
395 
396  const cWinVariant& operator=(BYTE* pbSrc) throw()
397  {
398  InitTypeInt((VARENUM)(VT_UI1 | VT_BYREF));
399  pbVal = pbSrc;
400  return *this;
401  }
402 
403  const cWinVariant& operator=(short* pnSrc) throw()
404  {
405  InitTypeInt((VARENUM)(VT_I2 | VT_BYREF));
406  piVal = pnSrc;
407  return *this;
408  }
409 
410 #ifdef _NATIVE_WCHAR_T_DEFINED
411  const cWinVariant& operator=(WORD* pnSrc) throw()
412  {
413  InitTypeInt((VARENUM)(VT_UI2 | VT_BYREF));
414  puiVal = pnSrc;
415  return *this;
416  }
417 #endif
418 
419  const cWinVariant& operator=(int* pnSrc) throw()
420  {
421  InitTypeInt((VARENUM)(VT_I4 | VT_BYREF));
422  pintVal = pnSrc;
423  return *this;
424  }
425 
426  const cWinVariant& operator=(UINT* pnSrc) throw()
427  {
428  InitTypeInt((VARENUM)(VT_UI4 | VT_BYREF));
429  puintVal = pnSrc;
430  return *this;
431  }
432 
433  const cWinVariant& operator=(long* pnSrc) throw()
434  {
435  InitTypeInt((VARENUM)(VT_I4 | VT_BYREF));
436  plVal = pnSrc;
437  return *this;
438  }
439 
440  const cWinVariant& operator=(ULONG* pnSrc) throw()
441  {
442  InitTypeInt((VARENUM)(VT_UI4 | VT_BYREF));
443  pulVal = pnSrc;
444  return *this;
445  }
446 
447 #if ! defined(UNDER_CE) && (defined(USE_64BIT) || (_WIN32_WINNT >= 0x0501) || defined(_ATL_SUPPORT_VT_I8))
448  const cWinVariant& operator=(LONGLONG nSrc) throw()
449  {
450  InitTypeInt(VT_I8);
451  llVal = nSrc;
452  return *this;
453  }
454 
455  const cWinVariant& operator=(LONGLONG* pnSrc) throw()
456  {
457  InitTypeInt((VARENUM)(VT_I8 | VT_BYREF));
458  pllVal = pnSrc;
459  return *this;
460  }
461 
462  const cWinVariant& operator=(ULONGLONG nSrc) throw()
463  {
464  InitTypeInt(VT_UI8);
465  ullVal = nSrc;
466  return *this;
467  }
468 
469  const cWinVariant& operator=(ULONGLONG* pnSrc) throw()
470  {
471  InitTypeInt((VARENUM)(VT_UI8 | VT_BYREF));
472  pullVal = pnSrc;
473  return *this;
474  }
475 #endif
476 
477  const cWinVariant& operator=(float* pfSrc) throw()
478  {
479  InitTypeInt((VARENUM)(VT_R4 | VT_BYREF));
480  pfltVal = pfSrc;
481  return *this;
482  }
483 
484  const cWinVariant& operator=(double* pfSrc) throw()
485  {
486  InitTypeInt((VARENUM)(VT_R8 | VT_BYREF));
487  pdblVal = pfSrc;
488  return *this;
489  }
490 
491 #ifndef UNDER_CE
492  void InternalSafeArray(const SAFEARRAY *pSrc)
493  {
494  ASSERT(pSrc != nullptr);
495  LPSAFEARRAY pCopy;
496  HRESULT hRes = ::SafeArrayCopy((LPSAFEARRAY)pSrc, &pCopy);
497  if (SUCCEEDED(hRes) && pCopy != nullptr)
498  {
499  ::SafeArrayGetVartype((LPSAFEARRAY)pSrc, &vt);
500  vt |= VT_ARRAY;
501  parray = pCopy;
502  }
503  else
504  {
505  vt = VT_ERROR;
506  scode = hRes;
507  }
508  }
509 
510  const cWinVariant& operator=(const SAFEARRAY *pSrc)
511  {
512  Clear();
513  if (pSrc != nullptr)
514  {
515  InternalSafeArray(pSrc);
516  }
517  return *this;
518  }
519 #endif
520 
521  // Comparison Operators
522  public:
523 
524 #ifndef UNDER_CE
525  COMPARE_t CompareVar(const VARIANT& varSrc) const
526  {
527  // VARCMP_EQ, VARCMP_LT, VARCMP_GT
528  // NOTE: NOT the same as COMPARE_t
529 #if ( _MSC_VER >= 1300 ) || defined(__GNUC__)
530  return ::VarCmp((VARIANT*)this, (VARIANT*)&varSrc, LOCALE_USER_DEFAULT, 0);
531 #else
532  return ::VarCmp((VARIANT*)this, (VARIANT*)&varSrc, LOCALE_USER_DEFAULT);
533 #endif
534  }
535  bool operator==(const VARIANT& varSrc) const throw()
536  {
537  // For backwards compatibility
538  if (vt == VT_NULL && varSrc.vt == VT_NULL)
539  return VARCMP_EQ;
540  return(CompareVar(varSrc) == VARCMP_EQ);
541  }
542  bool operator!=(const VARIANT& varSrc) const throw()
543  {
544  if (vt == VT_NULL && varSrc.vt == VT_NULL)
545  return VARCMP_EQ;
546  return(CompareVar(varSrc) != VARCMP_EQ);
547  }
548  bool operator<(const VARIANT& varSrc) const throw()
549  {
550  if (vt == VT_NULL && varSrc.vt == VT_NULL)
551  return false;
552  return(CompareVar(varSrc) == VARCMP_LT);
553  }
554  bool operator>(const VARIANT& varSrc) const throw()
555  {
556  if (vt == VT_NULL && varSrc.vt == VT_NULL)
557  return false;
558  return(CompareVar(varSrc) == VARCMP_GT);
559  }
560 #endif
561 
562  // Operations
563  public:
564  HRESULT Clear()
565  {
566  return ::VariantClear(this);
567  }
568  HRESULT Copy(const VARIANT* pSrc)
569  {
570  return ::VariantCopy(this, const_cast<VARIANT*>(pSrc));
571  }
572 
573  HRESULT CopyTo(BSTR* pstrDest) const;
574  HRESULT Attach(VARIANT* pSrc)
575  {
576  // Move pDest into this.
577  if (pSrc == nullptr)
578  return E_INVALIDARG;
579 
580  // Clear out the variant
581  HRESULT hRes = Clear();
582  if (!FAILED(hRes))
583  {
584  // Copy the contents and give control to cWinVariant
585  memcpy(this, pSrc, sizeof(VARIANT));
586  pSrc->vt = VT_EMPTY;
587  hRes = S_OK;
588  }
589  return hRes;
590  }
591 
592  HRESULT Detach(VARIANT* pDest)
593  {
594  // Move this into pDest.
595  ASSERT(pDest != nullptr);
596  if (pDest == nullptr)
597  return E_POINTER;
598 
599  // Clear out the variant
600  HRESULT hRes = ::VariantClear(pDest);
601  if (!FAILED(hRes))
602  {
603  // Copy the contents and remove control from cWinVariant
604  memcpy(pDest, this, sizeof(VARIANT));
605  vt = VT_EMPTY;
606  hRes = S_OK;
607  }
608  return hRes;
609  }
610  void Detach()
611  {
612  vt = VT_EMPTY;
613  }
614 
615  HRESULT ChangeType(VARTYPE vtNew, const VARIANT* pSrc = nullptr)
616  {
617  VARIANT* pVar = const_cast<VARIANT*>(pSrc);
618  // Convert in place if pSrc is nullptr
619  if (pVar == nullptr)
620  pVar = this;
621  // Do nothing if doing in place convert and vts not different
622  return ::VariantChangeType(this, pVar, 0, vtNew);
623  }
624 
625 #if 0
626  template< typename _TYPE >
627  void SetByRef(_TYPE* pT) throw()
628  {
629  Clear();
630  vt = CVarTypeInfo< _TYPE >::VT | VT_BYREF;
631  byref = pT;
632  }
633 #endif
634 
635  HRESULT WriteToStream(IStream* pStream);
636  HRESULT ReadFromStream(IStream* pStream);
637 
638  // Return the size in bytes of the current contents
639  ULONG GetSize() const;
640 
641  // Implementation
642  HRESULT InternalClear()
643  {
644  HRESULT hRes = Clear();
645  ASSERT(SUCCEEDED(hRes));
646  if (FAILED(hRes))
647  {
648  vt = VT_ERROR;
649  scode = hRes;
650  }
651  return hRes;
652  }
653 
654  void InternalCopy(const VARIANT* pSrc)
655  {
656  HRESULT hRes = Copy(pSrc);
657  if (FAILED(hRes))
658  {
659  vt = VT_ERROR;
660  scode = hRes;
661  }
662  }
663 #endif // _MFC_VER
664 
665  static inline BSTR GetBStr(VARIANT* pVar);
666 
667  UNITTEST2_PREDEF(cWinVariant);
668  };
669 
670  inline BSTR cWinVariant::GetBStr(VARIANT* pVar) // static
671  {
672  ASSERT(pVar != nullptr);
673  switch (pVar->vt)
674  {
675  case VT_BYREF | VT_VARIANT:
676  return cWinVariant::GetBStr(pVar->pvarVal);
677  case VT_BYREF | VT_BSTR:
678  return *pVar->pbstrVal;
679  case VT_BSTR:
680  return pVar->bstrVal;
681  default:
682  return nullptr;
683  }
684  }
685 };
686 
687 #ifndef _MFC_VER
688 typedef GrayLib::cWinVariant CComVariant; // alias
689 #endif
690 
691 #endif // _WIN32
692 #endif // _INC_cWinVariant_H
#define GRAYLIB_LINK
Definition: GrayLibBase.h:35
#define SUCCEEDED(x)
Definition: HResult.h:29
#define FAILED(x)
Definition: HResult.h:30
INT32 HRESULT
_WIN32 style error codes. INT32
Definition: SysTypes.h:465
#define ASSERT(exp)
Definition: cDebugAssert.h:87
int COMPARE_t
Definition: cKernel.h:38
Definition: IUnknown.h:68
Definition: cMesh.h:22
UNITTEST2_PREDEF(cQuadtree)
cStringW cWinString
Definition: cWinString.h:251
bool operator<(const cTimeDouble &dt1, const cTimeDouble &dt2)
Definition: cTimeDouble.h:234
bool operator!=(const cTimeDouble &dt1, const cTimeDouble &dt2)
Definition: cTimeDouble.h:254
bool operator==(const cTimeDouble &dt1, const cTimeDouble &dt2)
Definition: cTimeDouble.h:250
bool operator>(const cTimeDouble &dt1, const cTimeDouble &dt2)
Definition: cTimeDouble.h:242
static void Zero(void *pData, size_t nSizeBlock) noexcept
Definition: cMem.h:100