1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// Windows/PropVariant.cpp
2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "StdAfx.h"
4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
5baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "PropVariant.h"
6baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
7baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../Common/Defs.h"
8baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
9baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace NWindows {
10baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace NCOM {
11baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
12baa3858d3f5d128a5c8466b700098109edcad5f2repo syncCPropVariant::CPropVariant(const PROPVARIANT &varSrc)
13baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
14baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  vt = VT_EMPTY;
15baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  InternalCopy(&varSrc);
16baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
17baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
18baa3858d3f5d128a5c8466b700098109edcad5f2repo syncCPropVariant::CPropVariant(const CPropVariant &varSrc)
19baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
20baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  vt = VT_EMPTY;
21baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  InternalCopy(&varSrc);
22baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
23baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
24baa3858d3f5d128a5c8466b700098109edcad5f2repo syncCPropVariant::CPropVariant(BSTR bstrSrc)
25baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  vt = VT_EMPTY;
27baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  *this = bstrSrc;
28baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
29baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
30baa3858d3f5d128a5c8466b700098109edcad5f2repo syncCPropVariant::CPropVariant(LPCOLESTR lpszSrc)
31baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  vt = VT_EMPTY;
33baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  *this = lpszSrc;
34baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
35baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
36baa3858d3f5d128a5c8466b700098109edcad5f2repo syncCPropVariant& CPropVariant::operator=(const CPropVariant &varSrc)
37baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
38baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  InternalCopy(&varSrc);
39baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return *this;
40baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
41baa3858d3f5d128a5c8466b700098109edcad5f2repo syncCPropVariant& CPropVariant::operator=(const PROPVARIANT &varSrc)
42baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
43baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  InternalCopy(&varSrc);
44baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return *this;
45baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
46baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
47baa3858d3f5d128a5c8466b700098109edcad5f2repo syncCPropVariant& CPropVariant::operator=(BSTR bstrSrc)
48baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
49baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  *this = (LPCOLESTR)bstrSrc;
50baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return *this;
51baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
52baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
53baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const char *kMemException = "out of memory";
54baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
55baa3858d3f5d128a5c8466b700098109edcad5f2repo syncCPropVariant& CPropVariant::operator=(LPCOLESTR lpszSrc)
56baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
57baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  InternalClear();
58baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  vt = VT_BSTR;
59baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  wReserved1 = 0;
60baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  bstrVal = ::SysAllocString(lpszSrc);
61baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (bstrVal == NULL && lpszSrc != NULL)
62baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
63baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    throw kMemException;
64baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    // vt = VT_ERROR;
65baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    // scode = E_OUTOFMEMORY;
66baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
67baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return *this;
68baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
69baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
70baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
71baa3858d3f5d128a5c8466b700098109edcad5f2repo syncCPropVariant& CPropVariant::operator=(const char *s)
72baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
73baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  InternalClear();
74baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  vt = VT_BSTR;
75baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  wReserved1 = 0;
76baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UINT len = (UINT)strlen(s);
77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  bstrVal = ::SysAllocStringByteLen(0, (UINT)len * sizeof(OLECHAR));
78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (bstrVal == NULL)
79baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
80baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    throw kMemException;
81baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    // vt = VT_ERROR;
82baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    // scode = E_OUTOFMEMORY;
83baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
84baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
85baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
86baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (UINT i = 0; i <= len; i++)
87baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      bstrVal[i] = s[i];
88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return *this;
90baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
91baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
92baa3858d3f5d128a5c8466b700098109edcad5f2repo syncCPropVariant& CPropVariant::operator=(bool bSrc)
93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (vt != VT_BOOL)
95baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
96baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    InternalClear();
97baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    vt = VT_BOOL;
98baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
99baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  boolVal = bSrc ? VARIANT_TRUE : VARIANT_FALSE;
100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return *this;
101baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define SET_PROP_FUNC(type, id, dest) \
104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CPropVariant& CPropVariant::operator=(type value) \
105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  { if (vt != id) { InternalClear(); vt = id; } \
106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    dest = value; return *this; }
107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
108baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSET_PROP_FUNC(Byte, VT_UI1, bVal)
109baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSET_PROP_FUNC(Int16, VT_I2, iVal)
110baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSET_PROP_FUNC(Int32, VT_I4, lVal)
111baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSET_PROP_FUNC(UInt32, VT_UI4, ulVal)
112baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSET_PROP_FUNC(UInt64, VT_UI8, uhVal.QuadPart)
113baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSET_PROP_FUNC(const FILETIME &, VT_FILETIME, filetime)
114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
115baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic HRESULT MyPropVariantClear(PROPVARIANT *prop)
116baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
117baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  switch(prop->vt)
118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_UI1:
120baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_I1:
121baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_I2:
122baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_UI2:
123baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_BOOL:
124baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_I4:
125baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_UI4:
126baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_R4:
127baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_INT:
128baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_UINT:
129baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_ERROR:
130baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_FILETIME:
131baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_UI8:
132baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_R8:
133baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_CY:
134baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_DATE:
135baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      prop->vt = VT_EMPTY;
136baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      prop->wReserved1 = 0;
137baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return S_OK;
138baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
139baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return ::VariantClear((VARIANTARG *)prop);
140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
141baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
142baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CPropVariant::Clear()
143baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
144baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return MyPropVariantClear(this);
145baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
146baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
147baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CPropVariant::Copy(const PROPVARIANT* pSrc)
148baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
149baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  ::VariantClear((tagVARIANT *)this);
150baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  switch(pSrc->vt)
151baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
152baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_UI1:
153baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_I1:
154baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_I2:
155baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_UI2:
156baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_BOOL:
157baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_I4:
158baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_UI4:
159baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_R4:
160baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_INT:
161baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_UINT:
162baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_ERROR:
163baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_FILETIME:
164baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_UI8:
165baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_R8:
166baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_CY:
167baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_DATE:
168baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      memmove((PROPVARIANT*)this, pSrc, sizeof(PROPVARIANT));
169baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return S_OK;
170baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
171baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return ::VariantCopy((tagVARIANT *)this, (tagVARIANT *)const_cast<PROPVARIANT *>(pSrc));
172baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
173baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
174baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
175baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CPropVariant::Attach(PROPVARIANT *pSrc)
176baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
177baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  HRESULT hr = Clear();
178baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (FAILED(hr))
179baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return hr;
180baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  memcpy(this, pSrc, sizeof(PROPVARIANT));
181baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  pSrc->vt = VT_EMPTY;
182baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
183baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
184baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
185baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CPropVariant::Detach(PROPVARIANT *pDest)
186baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
187baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  HRESULT hr = MyPropVariantClear(pDest);
188baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (FAILED(hr))
189baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return hr;
190baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  memcpy(pDest, this, sizeof(PROPVARIANT));
191baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  vt = VT_EMPTY;
192baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return S_OK;
193baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
194baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
195baa3858d3f5d128a5c8466b700098109edcad5f2repo syncHRESULT CPropVariant::InternalClear()
196baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
197baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  HRESULT hr = Clear();
198baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (FAILED(hr))
199baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
200baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    vt = VT_ERROR;
201baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    scode = hr;
202baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
203baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return hr;
204baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
205baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
206baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid CPropVariant::InternalCopy(const PROPVARIANT *pSrc)
207baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
208baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  HRESULT hr = Copy(pSrc);
209baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (FAILED(hr))
210baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
211baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (hr == E_OUTOFMEMORY)
212baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      throw kMemException;
213baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    vt = VT_ERROR;
214baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    scode = hr;
215baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
216baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
217baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
218baa3858d3f5d128a5c8466b700098109edcad5f2repo syncint CPropVariant::Compare(const CPropVariant &a)
219baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
220baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (vt != a.vt)
221baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return MyCompare(vt, a.vt);
222baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  switch (vt)
223baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
224baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_EMPTY: return 0;
225baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    // case VT_I1: return MyCompare(cVal, a.cVal);
226baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_UI1: return MyCompare(bVal, a.bVal);
227baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_I2: return MyCompare(iVal, a.iVal);
228baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_UI2: return MyCompare(uiVal, a.uiVal);
229baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_I4: return MyCompare(lVal, a.lVal);
230baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_UI4: return MyCompare(ulVal, a.ulVal);
231baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    // case VT_UINT: return MyCompare(uintVal, a.uintVal);
232baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_I8: return MyCompare(hVal.QuadPart, a.hVal.QuadPart);
233baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_UI8: return MyCompare(uhVal.QuadPart, a.uhVal.QuadPart);
234baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_BOOL: return -MyCompare(boolVal, a.boolVal);
235baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_FILETIME: return ::CompareFileTime(&filetime, &a.filetime);
236baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case VT_BSTR:
237baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return 0; // Not implemented
238baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      // return MyCompare(aPropVarint.cVal);
239baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    default: return 0;
240baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
241baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
242baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
243baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}}
244