您的位置:首页 > 编程语言 > C语言/C++

VC自动化向导的bug2(vs2005使用Labview控件类时的错误)

2016-03-18 10:38 766 查看
   项目中用到Labview的slider控件,需要在程序中控制slider填充区域的颜色(图中绿色区域)

.


   颜色参数为属性分组中的Pointer中的FillColor属性.



   查找slider类的成员函数,希望找到能设置FillColor的函数,发现其中并没有直接设置的函数,但有一个获取CwPointer指针的函数

CWPointer * GetActivePointer()
{
CWPointer * result;
GetProperty(0x105, VT_DISPATCH, (void*)&result);
return result;
}   接着查找CwPointer的成员变量,发现了设置FillColor属性的方法

CWPointer : IDispatch
{
OLE_COLOR GetFillColor ( );
void PutFillColor ( OLE_COLOR _val );  于是尝试先通过slider变量获取Cwpointer属性,在调用Cwpointer的方法设置颜色,结果程序报错:提示CwPointer类为抽象类,不能实例化。由此发现了vs2005自动化向导的一个Bug:没有正确的定义控件类包含的所有接口类(根本就没有定义),需要自己手动添加这些接口类。

   手动添加接口类的方法:类视图->添加类->MFC->TypeLib中的MFC类



   在类型库中找到National Instrucments UI



   接口中找到CwPointer,生成类:



   查看刚刚添加的类,发现内部居然是CwBinding_CI的方法

// CCWPointer 包装类

class CCWPointer : public COleDispatchDriver
{
public:
CCWPointer(){} // 调用 COleDispatchDriver 默认构造函数
CCWPointer(LPDISPATCH pDispatch) : COleDispatchDriver(pDispatch) {}
CCWPointer(const CCWPointer& dispatchSrc) : COleDispatchDriver(dispatchSrc) {}

// 属性
public:

// 操作
public:

// CWBinding_CI 方法
public:
CString get_BindProperty()
{
CString result;
InvokeHelper(0x2, DISPATCH_PROPERTYGET, VT_BSTR, (void*)&result, NULL);
return result;
}
void put_BindProperty(LPCTSTR newValue)
{
static BYTE parms[] = VTS_BSTR ;
InvokeHelper(0x2, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue);
}

   而不是Cwpointer的方法,由此发现自动化向导的第二个Bug:添加的接口类名称与内部方法不匹配,是错乱的。之后为了找到真正的CwPointer方法类,将所有的接口都生成类,发现其类名和内部方法全是不匹配的,而且并没有CwPointer方法。

   控件研究到这一步,似乎无法再继续下去了,也已经对vs2005的自动化向导不报任何期望了(注:要不是开发Vega Pirme 2.2,必须要用vs2005,早就不用这个开发平台了!).这时想起上一次碰到自动化向导的bug,是参考vc6.0中的控件类解决的。因此这次再次尝试在VC6.0中使用slider控件并设置颜色。VS2005和VC6.0添加控件类的过程有所区别:

   vs2005:只创建slider类,类中要用到的其他接口类,一律不自动创建,而是直接定义为tlh文件中的抽象类(根本不能实例化,无法使用);

   vc6.0:在创建slider类的同时,直接创建类中用到的其他接口类(创建的是派生自COleDispatchDriver的接口类,可直接实例化调用)。

   经查看,vc6.0生成的接口类和方法是匹配的:

class CCWPointer : public COleDispatchDriver
{
public:
CCWPointer() {}		// Calls COleDispatchDriver default constructor
CCWPointer(LPDISPATCH pDispatch) : COleDispatchDriver(pDispatch) {}
CCWPointer(const CCWPointer& dispatchSrc) : COleDispatchDriver(dispatchSrc) {}

// Attributes
public:
VARIANT GetValue();
void SetValue(const VARIANT&);
long GetFillStyle();
void SetFillStyle(long);
CString GetName();
void SetName(LPCTSTR);
unsigned long GetFillColor();
void SetFillColor(unsigned long);
long GetIndex();
void SetIndex(long);
long GetStyle();
void SetStyle(long);
BOOL GetVisible();
void SetVisible(BOOL);
long GetMode();
void SetMode(long);
unsigned long GetColor();
void SetColor(unsigned long);
long GetValuePairIndex();
void SetValuePairIndex(long);

// Operations
public:
};

   于是将CCwpointer接口类拷至vs2005工程中,并对slider类做相应的修改:

CCWPointer GetActivePointer()
{
LPDISPATCH pDispatch;
GetProperty(0x105, VT_DISPATCH, (void*)&pDispatch);
return CCWPointer(pDispatch);
}

   返回类型由Cwpointer*改为CCWpointer,成功调用接口:

m_PowerVoltSlider.SetValue(20);
CCWPointer cwPointer = m_PowerVoltSlider.GetActivePointer();
COLORREF colorRed = RGB(255,0,0);
cwPointer.SetFillColor((OLE_COLOR)colorRed);

   最后:vc6.0生成的接口类也有个不影响使用的小错误:

void CCWPointer::SetFillColor(unsigned long propVal)
{
SetProperty(0x4, VT_I4, propVal);
}

   方法的参数为unsigned long型,但是SetProperty设置的属性VI_I4是signed int型,应改为VT_UI4.

// VARENUM usage key,
//
// [V] - May appear in a VARIANT.
// [T] - May appear in a TYPEDESC.
// [P] - may appear in an OLE property set.
// [S] - May appear in a Safe Array.
//
//
VT_EMPTY            [V]   [P]         // Not specified.
VT_NULL               [V]                // SQL-style Null.
VT_I2               [V][T][P][S]      // 2-byte signed int.
VT_I4               [V][T][P][S]      // 4-byte-signed int.
VT_R4               [V][T][P][S]      // 4-byte real.
VT_R8               [V][T][P][S]      // 8-byte real.
VT_CY               [V][T][P][S]      // Currency.
VT_DATE               [V][T][P][S]      // Date.
VT_BSTR               [V][T][P][S]      // Automation string.
VT_DISPATCH         [V][T]   [S]      // IDispatch.Far*
VT_ERROR            [V][T]   [S]      // Scodes.
VT_BOOL               [V][T][P][S]      // Boolean; True=-1, False=0.
VT_VARIANT            [V][T][P][S]      // VARIANT FAR*.
VT_DECIMAL            [V][T]   [S]      // 16 byte fixed point.
VT_RECORD            [V]   [P][S]      // User defined type
VT_UNKNOWN            [V][T]   [S]      // IUnknown FAR*.
VT_I1               [V][T]   [S]      // Char.
VT_UI1               [V][T]   [S]      // Unsigned char.
VT_UI2               [V][T]   [S]      // 2 byte unsigned int.
VT_UI4               [V][T]   [S]      // 4 byte unsigned int.
VT_INT               [V][T]   [S]      // Signed machine int.
VT_UINT             [V][T]   [S]      // Unsigned machine int.
VT_VOID                  [T]            // C-style void.
VT_HRESULT               [T]
VT_PTR                  [T]            // Pointer type.
VT_SAFEARRAY            [T]            // Use VT_ARRAY in VARIANT.
VT_CARRAY               [T]            // C-style array.
VT_USERDEFINED         [T]            // User-defined type.
VT_LPSTR               [T][P]         // Null-terminated string.
VT_LPWSTR               [T][P]         // Wide null-terminated string.
VT_FILETIME               [P]         //FILETIME
VT_BLOB                     [P]         //Length prefixed bytes
VT_STREAM                  [P]         //Name of the stream follows
VT_STORAGE                  [P]         //Name of the storage follows
VT_STREAMED_OBJECT         [P]         //Stream contains an object
VT_STORED_OBJECT         [P]         //Storage contains an object
VT_BLOB_OBJECT            [P]         //Blob contains an object
VT_CF                     [P]         //Clipboard format
VT_CLSID                  [P]         //A Class ID
VT_VECTOR                  [P]         //simple counted array
VT_ARRAY            [V]               // SAFEARRAY*.
VT_BYREF            [V]
VT_RESERVED


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  vc++