MSComm控件的几个疑难问题汇总
2016-10-23 10:49
176 查看
1.VARIANT和SAFEARRAY数据类型是什么鬼?
VARIANT、_variant_t、COleVariant数据类型
VARIANT及由之而派生的COleVariant类主要用于在OLE自动化中传递数据。实际上,VARIANT也只不过是一个新定义的结构罢了!它的主要成员包括一个联合体及一个变量。该联合体由各种类型的数据成员构成,而该变量则用来指明联合体中目前其作用的数据类型。
对于VARIANT变量的赋值:首先给vt成员赋值,指明数据类型,在对联合结构中相同数据类型的变量赋值。例如:
<span style="font-size:18px;font-weight: normal;">VARIANT vaData;//定义VARIANT类型变量 int a = 2001; vaData.vt = VT_I4;//指明整型数据 vaData.lVal = a;//赋值</span>
而_vatiant_t是VATIANT的封装类,其赋值可以采用强制类型转换,其构造函数会自动处理这些数据类型。使用时需加上#include<comdef.h>
如:
<span style="font-size:18px;font-weight: normal;">long l = 222; int i = 100; _variant_t lVal(l); lVal = (long)i;</span>
COleVariant的使用与_variant_t的方法基本一致,
如:
<span style="font-size:18px;font-weight: normal;">COleVariant v3 = _T("字符串"),v4 = (long)1999; CString str = (BSTR)v3.pbstrVal; long i = v4.lVal;</span>
SAFEARRAY(COleSafeArray)数据类型
这是一个安全数组,他可以根据系统环境自动调整其16位或32位的定义,并且不会被OLE改变。其实,我们完全没有必要了解他的具体定义,只要知道SAFEARRAY是另外的一个结构就好了。其中包括一个(void*)类型的指针pvData,其指向的内存就是存放有用数据的地方。简言之,从GetInput()函数返回的VARIANT类型变量中,找出parray指针,再从该指针指向的SAFEARRAY变量中找出pvData指针,就可以像访问数组一样取得所接收到的数据。
例一:把CString字符串类型数据转换成Variant类型数据从串口发送
如果是发送CString字符串,必须将其他类型转换为VARIANT类型变量才能发送。再上一个工程中点击打开链接,我们对发送的CString字符串做过强制转换。代码如下:
<span style="font-weight: normal;"><span style="font-size:18px;">void CSerialCommDlg::OnClickedButtonManualsend() { UpdateData(TRUE); m_ctrlComm.put_Output(COleVariant(m_strEditTxData));//发送数据 }</span></span>
例二:把variant类型数据从串口读出并转换成CString字符串类型数据
在串口事件处理函数OnComm()中,应用SAFEARRAY(COleSafeArray)类型变量。代码如下:
<span style="font-size:18px;font-weight: normal;">void CSerialCommDlg::Oncomm() { VARIANT variant_inp; COleSafeArray safearray_inp; LONG len, k; BYTE rxdata[2048]; CString strtemp; if (m_ctrlComm.get_CommEvent() == 2 ) //事件值为2表示接受缓冲区内有字符 { variant_inp = m_ctrlComm.get_Input(); //读缓冲区 safearray_inp = variant_inp; //数据类型转换 </span><span style="font-weight: normal;"><span style="font-size:18px;"> len = safearray_inp.GetOneDimSize(); //得到有效数据长度 for (k = 0; k < len; k++) safearray_inp.GetElement(&k, rxdata + k); //转换为BYTE型数组 for (k = 0; k < len; k++) { BYTE bt = *(char*)(rxdata + k); //字符型 strtemp.Format(_T("%c"),bt); //将字符送入临时变量中保存 //const char 与 const wchar_t不兼容 m_strEditRxData += strtemp; }</span> } UpdateData(FALSE); }</span>
2.MSComm是否可以脱离对话框而存在?
只需要我们在VIEW中的oncreate()函数中加上一些处理就好,并应用MSComm通信控件的Create()函数来创建。MSComm通信控件的Create()函数原型如下:
其中,UINT nID为该空间ID号。具体创建方法如下:
<span style="font-weight: normal;"><span style="font-size:18px;">m_MSComm.Create(NULL,0,CRect(0,0,0,0),this,IDC_MSCOMM1)</span></span>
3.如何发送ASCII码等于零和大于128的字符?
<span style="font-weight: normal;"><span style="font-size:18px;">//发送消息 void CSerialCommDlg::OnClickedButtonManualsend() { //UpdateData(TRUE); //m_ctrlComm.put_Output(COleVariant(m_strEditTxData));//发送数据 unsigned char chData[8]; chData[0] = 0; chData[1] = 1; chData[2] = 13; chData[3] = 12; chData[4] = 0; chData[5] = 10; chData[6] = 156; chData[7] = 255; CByteArray binData; //定义字节数组 binData.RemoveAll();//清空binData for (int i = 0; i < 8; i++) binData.Add(chData[i]); COleVariant var(binData);//将binData转换为Variant数据类型 m_ctrlComm.put_Output(var);//发送数据 }</span></span>
4.如何控制多个串口?
在使用MSComm控件时,1个MSComm控件只能同时对应一个串口。如果应用程序需要访问和控制多个串口,那么就必须使用多个MSComm控件。相关文章推荐
- Windows开发人员转为WEB开发人员之疑难问题汇总
- TD常见疑难问题汇总
- play框架配置使用过程中遇到的各种疑难问题汇总(学习同事经验)
- 安装Mysql5.7.10 winx64出现的几个问题汇总
- Centos6.4搭建Redis集群遇到的几个问题汇总
- VC疑难问题汇总
- 关于jar打包时的几个问题的汇总
- mysql几个常见问题汇总
- VC疑难问题汇总【转】太佩服这人了
- spark 2.X 疑难问题汇总
- 几个Office使用中的小问题解决方法汇总
- java报表软件FineReport数据库连接疑难问题解决方案汇总
- SAP PI接收开发中的几个疑难问题!
- AngularJS 疑难问题解决汇总
- 汇总Xcode使用中几个小问题
- 神器技巧汇总 和 疑难解答(常见问题)
- 最近遇到的几个Android疑难问题
- 汇总Xcode使用中几个小问题
- CorelDRAW中的几个常见问题汇总
- 正则表达式的汇总和几个常见问题的解答