MFC之COleVariant类

 

COleVariant 本质上是一个枚举,用同一种类型来表达不同的子类型。如同boost中的variant

 COleVariant类是对VARIANT结构的封装。
  VARIANT 结构包含两部分。其一是 VARTYPE 型的成员变量vt;其二是个联合类型,这个联合包含了VC常用的几乎所有类型。因为联合用的是相同的存储空间,因此对联合的内容的解释依赖于 vt。
  例如,
  若 vt 的值是 VT_UI2, 说明该联合被解释为short int. 并使用成员变量名 iVal。
  若 vt 的的值是 VT_BSTR,说明该联合被解释为 BSTR 类型。并使用成员变量名 bstrVal。
  若 vt 的的值是 VT_BSTR|VT_BYREF,说明该联合被解释为BSTR 型指针。并使用成员变量名 pbstrVal。
  它的构造函数具有极为强大的功能,当对象构造时首先调用VariantInit进行 初始化,然后根据参数中的标准类型调用相应的构造函数,并使用VariantCopy进行转换赋值操作,当VARIANT对象不在有效范围时,它的析构函 数就会被自动调用,由于析构函数调用了VariantClear,因而相应的内存就会被自动清除。除此之外,COleVariant的赋值操作符在与 VARIANT类型转换中为我们提供极大的方便。

若从数据库返回的是简单类型,如 short, long, 等,则直接引用既可。(主持人注:COleVariant类重载了“=”操作符,所以常用类型可以直接转换)若返回的是字符串类型,则有可能是 bstrVal 或pbstrVal。依赖于数据库服务程序。 BSTR 实际上就是个unicode 字符串,CString 的构造函数和赋值操作都能直接识别这一类型。
    
    AndySun问:
    VARIANT结构的vt成员可以为值VT_DECIMAL,当然,这个值在MSDN的帮助中似乎没有,但在VARIANT定义的源文件中确实有它的定义,它是在wtypes.h文件中定义的。但我不明白怎样将VT_DECIMAL的数据转换成常用的C数据类型,更想知道 VT_DECIMAL中究竟存放的是一个怎样的数据,应怎样将这个数据显示出来。谢谢!
    李海答:你可以使用COleVariant的ChangeType函数(相当于API函数VariantChangeType)将VT_DECIMAL转换为其他常用类型。

////////////////////////////////////////////////////////////////////

 例子

1 [cpp] view plaincopyprint?
2 01.COleVariant var(3.6f);  
3 02.float v = var.fltVal;  
4 03.CString str("testCOleVariant");  
5 04.COleVariant var2(str);  
6 05.CString cpStr(var2.bstrVal);  

  例子

01.CString CMFCPropertyGridProperty::m_strFormatChar = _T("%c");  
02.CString CMFCPropertyGridProperty::m_strFormatShort = _T("%d");  
03.CString CMFCPropertyGridProperty::m_strFormatLong = _T("%ld");  
04.CString CMFCPropertyGridProperty::m_strFormatUShort = _T("%u");  
05.CString CMFCPropertyGridProperty::m_strFormatULong = _T("%u");  
06.CString CMFCPropertyGridProperty::m_strFormatFloat = _T("%f");  
07.CString CMFCPropertyGridProperty::m_strFormatDouble = _T("%lf");  
08.  
09.CString CMFCPropertyGridProperty::FormatProperty()  
10.{  
11.    ASSERT_VALID(this);  
12.    ASSERT_VALID(m_pWndList);  
13.  
14.    COleVariant& var = m_varValue;  
15.  
16.    CString strVal;  
17.  
18.    .............  
19.  
20.    switch (var.vt)  
21.    {  
22.    case VT_BSTR:  
23.        strVal = var.bstrVal;  
24.        break;  
25.  
26.    case VT_I2:  
27.        strVal.Format(m_strFormatShort, (short)var.iVal);  
28.        break;  
29.  
30.    case VT_I4:  
31.    case VT_INT:  
32.        strVal.Format(m_strFormatLong, (long)var.lVal);  
33.        break;  
34.  
35.    case VT_UI1:  
36.        if ((BYTE)var.bVal != 0)  
37.        {  
38.            strVal.Format(m_strFormatChar, (TCHAR)(BYTE)var.bVal);  
39.        }  
40.        break;  
41.  
42.    case VT_UI2:  
43.        strVal.Format( m_strFormatUShort, var.uiVal);  
44.        break;  
45.  
46.    case VT_UINT:  
47.    case VT_UI4:  
48.        strVal.Format(m_strFormatULong, var.ulVal);  
49.        break;  
50.  
51.    case VT_R4:  
52.        strVal.Format(m_strFormatFloat, (float)var.fltVal);  
53.        break;  
54.  
55.    case VT_R8:  
56.        strVal.Format(m_strFormatDouble, (double)var.dblVal);  
57.        break;  
58.  
59.    case VT_BOOL:  
60.        strVal = var.boolVal == VARIANT_TRUE ? m_pWndList->m_strTrue : m_pWndList->m_strFalse;  
61.        break;  
62.  
63.    default:  
64.        // Unsupported type   
65.        strVal = _T("*** error ***");  
66.    }  
67.  
68.    return strVal;  
69.}  

COleVariant框架内容

01.class COleVariant : public tagVARIANT  
02.{  
03.    COleVariant(LPCTSTR lpszSrc);  
04.    COleVariant(LPCTSTR lpszSrc, VARTYPE vtSrc); // used to set to ANSI string   
05.    COleVariant(CString& strSrc);  
06.  
07.    COleVariant(BYTE nSrc);  
08.    COleVariant(short nSrc, VARTYPE vtSrc = VT_I2);  
09.    COleVariant(long lSrc, VARTYPE vtSrc = VT_I4);  
10.    COleVariant(const COleCurrency& curSrc);  
11.  
12.    COleVariant(float fltSrc);  
13.    COleVariant(double dblSrc);  
14.    COleVariant(const COleDateTime& timeSrc);  
15.....................................  
16.    const COleVariant& operator=(float fltSrc);  
17.    const COleVariant& operator=(double dblSrc);  
18.    const COleVariant& operator=(const COleDateTime& dateSrc);  
19.  
20.    const COleVariant& operator=(const CByteArray& arrSrc);  
21.    const COleVariant& operator=(const CLongBinary& lbSrc);  
22.};  
23.  
24.    void Clear();  
25.    void ChangeType(VARTYPE vartype, LPVARIANT pSrc = NULL);  
26.    void Attach(VARIANT& varSrc);  
27.    VARIANT Detach();  
28.   void GetByteArrayFromVariantArray(CByteArray& bytes);  
29.void SetString(LPCTSTR lpszSrc, VARTYPE vtSrc); // used to set ANSI string   
30.    operator LPVARIANT();  
31.    operator LPCVARIANT() const  
32./////////////////////////////////////////////////////////////////////////////////   
33.struct tagVARIANT  
34.    {    union   
35.        {  
36.        struct __tagVARIANT  
37.            {  
38.    VARTYPE vt;  
39.    .......................  
40.            union   
41.                {  
42.                LONGLONG llVal;  
43.                LONG lVal;  
44.                BYTE bVal;  
45.                SHORT iVal;  
46.                FLOAT fltVal;  
47.                DOUBLE dblVal;  
48.                ...........  
49.                DATE date;  
50.                BSTR bstrVal;  
51.                IUnknown *punkVal;  
52.     IDispatch *pdispVal;  
53.    ..............  
54.    }  
55.      
56.COleVariant::COleVariant(float fltSrc)  
57.        { vt = VT_R4; fltVal = fltSrc; }  
58._AFXDISP_INLINE COleVariant::COleVariant(CString& strSrc)  
59.        { vt = VT_EMPTY; *this = strSrc; }  
60.      
61.const COleVariant& COleVariant::operator=(const CString& strSrc)  
62.{  
63.    // Free up previous VARIANT   
64.    Clear();  
65.  
66.    vt = VT_BSTR;  
67.    bstrVal = strSrc.AllocSysString();  
68.  
69.    return *this;  
70.    }  
71.      
72.typedef unsigned short VARTYPE;  
73.    
75. * VARENUM usage key,  
76. *  
77. * * [V] - may appear in a VARIANT  
78. * * [T] - may appear in a TYPEDESC  
79. * * [P] - may appear in an OLE property set  
80. * * [S] - may appear in a Safe Array  
81. *  
82. *  
83. *  VT_EMPTY            [V]   [P]     nothing  
84. *  VT_NULL             [V]   [P]     SQL style Null  
85. *  VT_I2               [V][T][P][S]  2 byte signed int  
86. *  VT_I4               [V][T][P][S]  4 byte signed int  
87. *  VT_R4               [V][T][P][S]  4 byte real  
88. *  VT_R8               [V][T][P][S]  8 byte real  
89. *  VT_CY               [V][T][P][S]  currency  
90. *  VT_DATE             [V][T][P][S]  date  
91. *  VT_BSTR             [V][T][P][S]  OLE Automation string  
92. *  VT_DISPATCH         [V][T]   [S]  IDispatch *  
93. *  VT_ERROR            [V][T][P][S]  SCODE  
94. *  VT_BOOL             [V][T][P][S]  True=-1, False=0  
95. *  VT_VARIANT          [V][T][P][S]  VARIANT *  
96. *  VT_UNKNOWN          [V][T]   [S]  IUnknown *  
97. *  VT_DECIMAL          [V][T]   [S]  16 byte fixed point  
98. .......................................  
99.  
100.enum VARENUM  
101.    {   VT_EMPTY    = 0,  
102.    VT_NULL = 1,  
103.    VT_I2   = 2,  
104.    VT_I4   = 3,  
105.    VT_R4   = 4,  
106.    VT_R8   = 5,  
107.    VT_CY   = 6,  
108.    VT_DATE = 7,  
109.    VT_BSTR = 8,  
110.    .........................................  
111.        } ;  

COleVariant功能:
  COleVariant类是对VARIANT结构的封装。它的构造函数具有极为强大的功能:
  1、当对象构造时首先调用VariantInit进行 初始化,然后根据参数中的标准类型调用相应的构造函数,并使用VariantCopy进行转换赋值操作;
  2、当VARIANT对象不在有效范围时,它的析构函 数就会被自动调用,由于析构函数调用了VariantClear,因而相应的内存就会被自动清除。
  COleVariant是数据库常用到的数据类型。它可以是字串,整型值,日期等。知道怎样将它转换为CString很有用处。
  例如:设有CString A; COleVariant B; 来看看怎样将COleVariant转换为CString:
  switch(B.vt){
  case VT_BSTR: A=V_BSTRT(&B); break;//COleVariant是一个字串
  case VT_I2: A.Format(_T("%hd"),V_I2(&B));break;//是短整型
  case VT_I4: A.Format(_T("%d"),V_I4(&B));break;//是长整型
  case VT_R4: A.Format(_T("%e"),(double)V_R4(&B));break;//是浮点数
  case VT_R8: A.Format(_T("%e"),V_R8(&B));break;//是浮点数
  case VT_CY: A=COleCurrency(B).Format();break;//是货币值
  case VT_DATE: A=COleDateTime(B).Format("%Y-%m-%d");break;//是日期
  case VT_BOOL: A=V_BOOL(&B)?"True":"False";break;//是布尔值}

原文地址:https://www.cnblogs.com/yangxx-1990/p/4885236.html