来自:http://www.vckbase.com/index.php/video/listview/fid/2/sid/14
本节内容:
1、IDispatch的简介与作用
2、常用的COM数据类型
3、COM数据类型的转换
4、VARIANT类型的派生类
1、IDispatch的简介与作用
INT,INT*, UINT, UINT*, LONG, LONG*, ULONG,ULONG*,
FLOAT, FLOAT*, DOUBLE,DOUBLE*, VARIANT_BOOL, VARIANT_BOOL*,
BSTR, BSTR*,
IUnknown*, IUnknown**,IDispatch*, IDispatch**, VARIANT, VARIANT*
typedef short VARIANT_BOOL;
/*0 == FALSE, -1 == TRUE */
BSTR bstr = L"HelloUIPower";
之所有错误,是因为这样子的字符串前面没有计数值。
BSTR bstrA = SysAllocString(L"Hello BSTR");
BSTR bstrB = SysAllocStringLen(bstrA, SysStringLen(bstrA));
SysFreeString(bstrA);
SysFreeString(bstrB);
VARIANT var;
VariantInit(&var);
//此时 var.vt == VT_EMPTY;
//...其它操作
VariantClear(&var);
VARIANT var;
VariantInit(&var);
var.vt = VT_I4; //为什么vt是VT_I4呢?
var.lVal = 100;
VariantClear(&var);
//查看VARIANT结构体定义之前的注释可以查看到VT_I4与数据类型的对应关系,同时也可以查看到VT_I2,VT_R4等与相应数据类型的对应关系。
VARIANTvar;
VariantInit(&var);
var.vt= VT_R4;
var.fltVal= 1.23f;
VariantClear(&var);
VARIANT var;
VariantInit(&var);
var.vt = VT_BSTR;
var.bstrVal = SysAllocString(L"HelloUIPower");
VariantClear(&var);
VARIANTvar;
VariantInit(&var);
var.vt= VT_BOOL;
var.boolVal= VARIANT_FALSE;
VariantClear(&var);
if (var.vt == VT_I4)
{
long lValue = var.lVal;
}
else if (var.vt == VT_R4)
{
float fValue = var.fltVal;
}
else if (var.vt == VT_BSTR)
{
BSTR bstrValue = var.bstrVal;
}
elseif (var.vt == VT_BOOL)
{
VARIANT_BOO LvarbValue = var.boolVal;
}
3、COM数据类型的转换
//LONG转换成FLOAT
VARIANT var;
VariantInit(&var);
var.vt = VT_I4;
var.lVal = 100;
VariantChangeType(&var,&var,0, VT_R4);
if (var.vt == VT_R4)
{
float fValue= var.fltVal;
}
VariantClear(&var);
//LONG转换成BSTR
VARIANT var;
VariantInit(&var);
var.vt = VT_I4;
var.lVal = 100;
VariantChangeType(&var,&var,0,VT_BSTR);
if (var.vt == VT_BSTR)
{
BSTR fValue = var.bstrVal;
}
VariantClear(&var);
4、VARIANT类型的派生类
直接通过VARIANT API,比如VariantInit, VariantClear等来操作VARIANT比较麻烦,不方便。
给VARIANT赋值也需要设置VARIANT.vt,再设置VARIANT.lVal或VARIANT.fltVal等,也比较麻烦,不方便。
于是有人编写了派生类(子类)来继承VARIANT,然后在派生类中拓展VARIANT的使用方法,使VARIANT的使用更方便,更直接。
_variant_t是VC为支持COM类型而自带的VARIANT派生类,在VisualStudio安装目录\VC\include\comutil.h中定义。
CComVariant是ATL库为支持COM类型而自带的VARIANT派生类,在Visual Studio安装目录\VC\atlmfc\include\atlcomcli.h中定义。
COleVariant是MFC库为支持COM类型而自带的VARIANT派生类,在Visual Studio安装目录\VC\atlmfc\include\afxdisp.h中定义。
CComVariant简介
CComVariant的构造与析构
所以使用CComVariant代替VARIANT,就不需要再使用VariantInit()函数与VariantClear()函数。
CComVariant的构造方法
CComVariant的赋值方法
//清除CComVariant,调用了VariantClear清除本身。
//关联一个VARIANT,被关联后pSrc->vt=VT_EMPTY,CComVariant获得了关联对象的控制权。*pSrc这时不再使用,同时也无需调用VariantClear(pSrc)函数。
//Attack的反向过程,把CComVariant控制权交给*pDest对象,CComVariant本身的vt=VT_EMPTY。在不使用*pDest对象时,需要调用VariantClear(pDest)函数。
// Section3Demo1.cpp
//
#include "stdafx.h"
#include <oaidl.h>
#include <atlbase.h>
#include <atlcomcli.h>
int _tmain(int argc, _TCHAR* argv[])
{
//BSTR的使用
{
BSTR bstrA = SysAllocString(L"Hello BSTR");
BSTR bstrB = SysAllocStringLen(bstrA, SysStringLen(bstrA));
SysFreeString(bstrA);
SysFreeString(bstrB);
}
//用VARIANT保存LONG
{
VARIANT var;
VariantInit(&var);
var.vt = VT_I4;
var.lVal = 100;
VariantClear(&var);
int i = 0;
i++;
}
//用VARIANT保存FLOAT
{
VARIANT var;
VariantInit(&var);
var.vt = VT_R4;
var.fltVal = 1.23f;
VariantClear(&var);
}
//用VARIANT保存BSTR
{
VARIANT var;
VariantInit(&var);
var.vt = VT_BSTR;
var.bstrVal = SysAllocString(L"Hello World");
VariantClear(&var);
}
//用VARIANT保存布尔类型
{
VARIANT var;
VariantInit(&var);
var.vt = VT_BOOL;
var.boolVal = VARIANT_FALSE;
VariantClear(&var);
}
//从VARIANT读取相应类型的值
{
VARIANT var;
VariantInit(&var);
var.vt = VT_I4;
var.lVal = 100;
if (var.vt == VT_I4)
{
LONG lValue = var.lVal;
}
else if (var.vt == VT_R4)
{
FLOAT fValue = var.fltVal;
}
else if (var.vt == VT_BSTR)
{
BSTR bstrValue = var.bstrVal;
}
else if (var.vt == VT_BOOL)
{
VARIANT_BOOL varbValue = var.boolVal;
}
VariantClear(&var);
}
//COM数据类型的转换,LONG转成FLOAT
{
VARIANT var;
VariantInit(&var);
var.vt = VT_I4;
var.lVal = 100;
VariantChangeType(&var,&var,0, VT_R4);
if (var.vt == VT_R4)
{
FLOAT fValue = var.fltVal;
}
VariantClear(&var);
}
//COM数据类型的转换,LONG转成BSTR
{
VARIANT var;
VariantInit(&var);
var.vt = VT_I4;
var.lVal = 100;
VariantChangeType(&var,&var,0, VT_BSTR);
if (var.vt == VT_BSTR)
{
BSTR fValue = var.bstrVal;
}
VariantClear(&var);
}
//CComVariant的构造方法
{
VARIANT varA;
CComVariant varB;
CComVariant varC(varA);
CComVariant varD(varB);
CComVariant varE(L"Hello CComVariant");
CComVariant varF("CComVariant");
CComVariant varG(true);
CComVariant varH(100L);
CComVariant varI(1.23f);
//....
}
//CComVariant的赋值方法
{
VARIANT varA;
CComVariant varB;
CComVariant varC;
varC = varA;
varC = varB;
varC = true;
varC = 100L;
varC = 1.23f;
varC = L"Hello CComVariant";
varC = "Hello CComVariant";
//....
}
//CComVariant与VARIANT的关联
{
VARIANT varA;
VariantInit(&varA);
varA.vt = VT_I4;
varA.lVal = 100;
CComVariant varB;
CComVariant varC(100L);
VARIANT varD;
VariantInit(&varD);
//Attach
varB.Attach(&varA); //之后无需调用VariantClear(&varA);
//Detach
varC.Detach(&varD);
VariantClear(&varD); //需要调用VariantClear(&varD);
}
return 0;
}