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的方法
而不是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生成的接口类和方法是匹配的:
于是将CCwpointer接口类拷至vs2005工程中,并对slider类做相应的修改:
返回类型由Cwpointer*改为CCWpointer,成功调用接口:
最后:vc6.0生成的接口类也有个不影响使用的小错误:
方法的参数为unsigned long型,但是SetProperty设置的属性VI_I4是signed int型,应改为VT_UI4.
.
颜色参数为属性分组中的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++ 中ListCtrl经验总结
- VC++实现程序开机启动运行的方法
- VC++中HTControl控件类的CHTSlider控制杆控件类简介
- VC++中HTControl控制类使用之CHTDlgBase对话框基类实例
- Vc++ 控件List Control用法总结
- MFC控件大小随窗体大小而改变
- VC++的if语句应用范围分析
- VC++在TXT文件指定位置追加内容的方法
- VC++植物大战僵尸中文版修改器实现代码
- CISBitmap派生的VC++位图透明类实例
- VC++创建msi文件的方法
- VC++中图像处理类CBitmap的用法
- VC++的combobox控件用法汇总
- VC++中内存对齐实例教程
- VC++实现通过API来查看程序错误信息的方法
- VC++进度条process Bar的用法实例
- VC++操作SQLite简单实例
- 浅谈VC++中的内联
- VC++实现CStdioFile写入及读取文件并自动换行的方法
- VC++基于Dx实现的截图程序示例代码