几个关于MSCOMM控件串口通信编程的问题??

时间:2022-09-06 10:36:11
在学习串口编程,碰到几个问题,还清大虾指教!!

COleVariant myVar;           //先定义一个变量
COleSafeArray safearray_inp;
LONG len, k;
BYTE rxdata[2048];
CString strTemp(_T(""));
if(m_ctrlComm.get_CommEvent() == 2)
{
myVar.Attach(m_ctrlComm.get_Input()); //我这个GetInput的返回值是VARIANT
safearray_inp = myVar;
len = safearray_inp.GetOneDimSize();
for(k = 0; k < len; k++)
{
safearray_inp.GetElement(&k, rxdata+k);
}
for(k = 0; k < len; k++)
{
BYTE bt = *(char *)(rxdata+k);
strTemp.Format(_T("%c"), bt);
m_strEditRxData += strTemp;
}

第一个问题:COleVariant和COleSafeArray 到底有什么区别??我知道COleVariant是一个封装了VARIANT结构体的类,主要用于OLE自动化中传输数据(书上说的),而COleSafeArray是一种用于OLE自动化安全类型,这个程序我如果直接只定义一个COleSafeArray变量把

myVar.Attach(m_ctrlComm.get_Input()); //我这个GetInput的返回值是VARIANT
safearray_inp = myVar;

直接改为:

safearray_inp = m_ctrlComm.get_Input();

或者

safearray_inp.Attach(m_ctrlComm.get_Input());

就是不用COleVariant中转,好像结果没有任何问题,跟上面的程序结果一样!所以不明白这两个类具体有什么差别???

第二个问题:程序中rxdata原本就是BYTE行的数组,为什么在增加到strTemp之前要用上这句话:

BYTE bt = *(char *)(rxdata+k);

他最后不是把BYTE型变量又强制转化为BYTE变量,不知道有什么用!!我觉得直接用

BYTE bt = rxdata[k];

不是更方便!!!甚至可以直接把上面程序简化为:

BYTE rxdata;
for(k = 0; k < len; k++)
{
safearray_inp.GetElement(&k, &rxdata);
strTemp += rxdata;
}
m_strEditRxData += strTemp;

这样程序貌似简化很多!!!测试效果也几乎一样,暂时没有发现有什么差别,所以不知道

BYTE bt = *(char *)(rxdata+k);

这条语句有什么意义??????


第三个问题:就我测试了这段代码?可以接受英文字符很正常,但是不能够接收中文字符,用什么方法可以把COleVariant(或者是COleSafeArray)类变量直接转化为CString类的变量,而且可以支持中文字符!!!
因为发送的时候用:

m_ctrlComm.put_Output(COleVariant(m_strEditTxData));

发送中文字符时很正常的,就是CString类本来是支持中文字符的,但是通过BYTE或者是CByteArray转化一下再存入CString字符串中就变成了乱码??我知道因为BYTE其实是unsigned char类型,所以不能存储中文国标码字符,而CString是支持Unicode编码的,是支持中文字符的,所以这种转化肯定不能接收中文字符!!
所以想请问一下大虾,有什么方法可以让串口接收到中文字符,并可以显示出来!!!谢谢!!
    我测试过网上有些串口调试助手是支持中文字符的!!不确定他们是不是用MSCOMM控件开发的,有可能是用Windows API开发的,我想知道如果用MSCOMM控件,怎么样才可以实现能够接收中文字符!!谢谢!!

     求大虾帮帮忙!!呵呵!初学者多多指教!!

26 个解决方案

#1


问题1:
COleSafeArray继承COleVariant,但又属于COleVariant的一个类型VT_ARRAY。
而COleSafeArray的每个元素又可以是COleVariant。
在网络环境中,数组是不能直接传递的,而必须将其包装成SafeArray,赋给COleVariant。
问题2:
你说的都对,只是编程习惯问题,两者是等效的。
问题3:
中文是接受过来了,但是你不能像下边这样 一个字节一个字节的取。因为汉字至少是2字节(根据编码不同)
        BYTE bt = *(char *)(rxdata+k);
        strTemp.Format(_T("%c"), bt);
        m_strEditRxData += strTemp;

直接CString(m_ctrlComm.get_Input())就应该有你要的结果了。

#2


引用 1 楼 ynb119 的回复:
问题1:
COleSafeArray继承COleVariant,但又属于COleVariant的一个类型VT_ARRAY。
而COleSafeArray的每个元素又可以是COleVariant。
在网络环境中,数组是不能直接传递的,而必须将其包装成SafeArray,赋给COleVariant。
问题2:
你说的都对,只是编程习惯问题,两者是等效的。
问题3:……

如果在网络环境中,数组是不能直接传递的,而必须将其包装成SafeArray,那发送程序的时候好像是用

m_ctrlComm.put_Output(COleVariant(m_strEditTxData));

为什么不是用COleSafeArray,那直接把m_ctrlComm.get_Input()的值赋给COleSafeArray也可以哦!!只是说一般这个函数的返回值是COleVariant,如果赋给COleSafeArray的话,C++又自动完成了类型转换!其实本质上和这两句差距不大:

myVar.Attach(m_ctrlComm.get_Input()); //我这个GetInput的返回值是VARIANT
safearray_inp = myVar;

是这个意思吗??

关于第三个问题,接收中文的方法的话,用CString(m_ctrlComm.get_Input())貌似不可以,接收到的全部是乱码????而且接收英文字符也有问题!!!!
这是改后的代码:

//接收中文字符
strTemp = CString(m_ctrlComm.get_Input());
m_strEditRxData += strTemp;

//接收二进制

/*myVar.Attach(m_ctrlComm.get_Input()); //我这个GetInput的返回值是VARIANT
safearray_inp = myVar;
len = safearray_inp.GetOneDimSize();
for(k = 0; k < len; k++)
{
safearray_inp.GetElement(&k, &rxdata);
strTemp += rxdata;
}
m_strEditRxData += strTemp;*/

#3


引用 1 楼 ynb119 的回复:
问题1:
COleSafeArray继承COleVariant,但又属于COleVariant的一个类型VT_ARRAY。
而COleSafeArray的每个元素又可以是COleVariant。
在网络环境中,数组是不能直接传递的,而必须将其包装成SafeArray,赋给COleVariant。
问题2:
你说的都对,只是编程习惯问题,两者是等效的。
问题3:……

谢谢啊!!!

#4


好问题!
加油!

#5


>>C++又自动完成了类型转换!其实本质上和这两句差距不大
你说的是对的。
>>用CString(m_ctrlComm.get_Input())貌似不可以,接收到的全部是乱码?
乱码可能是你发送方和接收方用的字符集不一样,比如说发送方是Mutibyte而接收方是UNICODE。

#6


#1 得分:0 回复于: 2013-01-08 17:05:36 
问题1:
COleSafeArray继承COleVariant,但又属于COleVariant的一个类型VT_ARRAY。
而COleSafeArray的每个元素又可以是COleVariant。
在网络环境中,数组是不能直接传递的,而必须将其包装成SafeArray,赋给COleVariant。
问题2:
你说的都对,只是编程习惯问题,两者是等效的。
问题3:
中文是接受过来了,但是你不能像下边这样 一个字节一个字节的取。因为汉字至少是2字节(根据编码不同)
        BYTE bt = *(char *)(rxdata+k);
        strTemp.Format(_T("%c"), bt);
        m_strEditRxData += strTemp;

直接CString(m_ctrlComm.get_Input())就应该有你要的结果了。

#7


引用 5 楼 ynb119 的回复:
>>C++又自动完成了类型转换!其实本质上和这两句差距不大
你说的是对的。
>>用CString(m_ctrlComm.get_Input())貌似不可以,接收到的全部是乱码?
乱码可能是你发送方和接收方用的字符集不一样,比如说发送方是Mutibyte而接收方是UNICODE。
 应该不会是字符集不一样吧!!!我是同一个程序生成的软件,两个软件直接对发!!或者发发送接收方短路自己发自己接,接到的也是乱码啊1!!!效果图如下:
几个关于MSCOMM控件串口通信编程的问题??

跟你说一下具体情况,就是发送单个字符貌似没有问题,但是一旦发送多个字符或者中文都是乱码!!!!

#8


引用 5 楼 ynb119 的回复:
>>C++又自动完成了类型转换!其实本质上和这两句差距不大
你说的是对的。
>>用CString(m_ctrlComm.get_Input())貌似不可以,接收到的全部是乱码?
乱码可能是你发送方和接收方用的字符集不一样,比如说发送方是Mutibyte而接收方是UNICODE。
还有一个问题要请教你如果用CString(m_ctrlComm.get_Input())应该会自动把接收到的数据(应该是COleVariant型)转化为CString类型,这样的直接用构造函数转换会不会有问题!!貌似COleVariant类型变量内部集成了一个联合体,可以存储各种变量,CString可以根据实际类型自动完成转换吗??谢谢啊!!!

#9


>>貌似COleVariant类型变量内部集成了一个联合体,可以存储各种变量,CString可以根据实际类型自动完成转换吗??谢谢啊!!!
一般来说是可以的(VT_BSTR类型)。但是对于VT_ARRAY我也没试过。可能真的不行。

试试下边的。

发送方  COleVariant myVar = CString("XXXXX");
接收方  CString(m_ctrlComm.get_Input());

#10


引用 9 楼 ynb119 的回复:
>>貌似COleVariant类型变量内部集成了一个联合体,可以存储各种变量,CString可以根据实际类型自动完成转换吗??谢谢啊!!!
一般来说是可以的(VT_BSTR类型)。但是对于VT_ARRAY我也没试过。可能真的不行。

试试下边的。

发送方  COleVariant myVar = CString("XXXXX");
接收方  CString(……

我发送大概是这样的啊!!!

UpdateData(true);
//发送字符
m_ctrlComm.put_Output(COleVariant(m_strEditTxData));

m_strEditTxData是CString类的变量!!也就是与文本框关联的变量!!!!这个程序原本发送英文字符时正常的!!!
就是把字符强制转化为COleVariant类啊!!1

#11


看来 CString(m_ctrlComm.get_Input());不太好用,这我也不知道怎么回事了。

VARIANT var =m_ctrlComm.get_Input();
 CString(var.bstrVal)
会是什么结果?

#12


编码方式不同?
Unicode与多字节 界面显示不同

#13


m_ctrlComm.get_Input() 取回来的是data 不是 string 吧?

#14


引用 11 楼 ynb119 的回复:
看来 CString(m_ctrlComm.get_Input());不太好用,这我也不知道怎么回事了。

VARIANT var =m_ctrlComm.get_Input();
 CString(var.bstrVal)
会是什么结果?

没有任何显示,也就是说接收到的数据不是存在bstrVal里面!!

#15


引用 12 楼 arpnet99 的回复:
编码方式不同?
Unicode与多字节 界面显示不同

能不能具体说清楚一点,我的软件环境是unicode,怎么解决这个问题!!谢谢!!!!

#16


引用 15 楼 li460135301 的回复:
引用 12 楼 arpnet99 的回复:编码方式不同?
Unicode与多字节 界面显示不同
能不能具体说清楚一点,我的软件环境是unicode,怎么解决这个问题!!谢谢!!!!

那很有可能是编码方式不同引起的。
需要用这个函数MultiByteToWideChar转换一下。
或者可以先直接把工程改为多字节测试一下,是不是这个问题。

#17


引用 16 楼 arpnet99 的回复:
引用 15 楼 li460135301 的回复:引用 12 楼 arpnet99 的回复:编码方式不同?
Unicode与多字节 界面显示不同
能不能具体说清楚一点,我的软件环境是unicode,怎么解决这个问题!!谢谢!!!!
那很有可能是编码方式不同引起的。
需要用这个函数MultiByteToWideChar转换一下。
或者可以先直接把工程改为多字节测试一……

工程切换到多字节依然是乱码!!用CString(m_ctrlComm.get_Input())
几个关于MSCOMM控件串口通信编程的问题??

#18


调试一下,看看m_ctrlComm.get_Input()中的数据是不是字符串,如果不是的话。是不能正常显示的。要先格式化一下。

#19


引用 18 楼 arpnet99 的回复:
调试一下,看看m_ctrlComm.get_Input()中的数据是不是字符串,如果不是的话。是不能正常显示的。要先格式化一下。

我如果发送一串字符的话,结果是字符串!您看下截图效果!!
一下是发送as两个英文字符的截图:
几个关于MSCOMM控件串口通信编程的问题??
收到的是乱码???转化为CString之后,但是在COleVariant或者COleSafeArray是正确的!

以下是发送“往”这个中文字符的截图:
几个关于MSCOMM控件串口通信编程的问题??
接收到在COleVariant中的值为cdf9,我专门查了一下这是“往”这个字的“GBK编码”就是国标码!所以传到CString中肯定是乱码!CString应该是用unicode编码的!并不是unicode编码!!!以下是往这个字的各种编码值:
几个关于MSCOMM控件串口通信编程的问题??


怎么解决这个问题呢????

#20


引用 18 楼 arpnet99 的回复:
调试一下,看看m_ctrlComm.get_Input()中的数据是不是字符串,如果不是的话。是不能正常显示的。要先格式化一下。

在MBCS环境下调试的结果一模一样!!!!

#21


‘as’ 那个 0 呢? (sz)标记

#22


引用 21 楼 schlafenhamster 的回复:
‘as’ 那个 0 呢? (sz)标记

是不是在CString转化为COleVariant时会自动把结束标志给截掉,也就是说这个数不通过串口发送过去!因为我们做串口一般发送的话还是不希望收到0 的吧!如果要发送二进制代码的话就用CByteArray来填充COleVariant,不用CString了!!!

#23


CString 到 BSTR 可能没有 0, 因为 BSTR 前面 有 长度。
你 这样 没有 0,就不是 字符串。 要 处理一下。

#24


引用 18 楼 arpnet99 的回复:
调试一下,看看m_ctrlComm.get_Input()中的数据是不是字符串,如果不是的话。是不能正常显示的。要先格式化一下。

我这里还调试了一下!发现这个现象,就是我发送“往”时发送的是这个字的unicode编码,这个应该没有错,因为我先把他存在COleVariant变量中查看了一下,COleVariant变量的值是5f80,也就是unciode编码值,但是接受到的数据不是unicode编码值,也就是说我把“往”放到COleVariant变量(5f80)放到MSCOMM空间中去发送,实际上发送的是cdf9(或者说至少接收到的是cdf9),也就是MBCS编码!!!而并不是接收到unicode编码的5f80,不知道什么问题!!!而5f80显然不是“往”的编码,所以接收到的数据就是乱码的!!

#25


引用 16 楼 arpnet99 的回复:
引用 15 楼 li460135301 的回复:引用 12 楼 arpnet99 的回复:编码方式不同?
Unicode与多字节 界面显示不同
能不能具体说清楚一点,我的软件环境是unicode,怎么解决这个问题!!谢谢!!!!
那很有可能是编码方式不同引起的。
需要用这个函数MultiByteToWideChar转换一下。
或者可以先直接把工程改为多字节测试一……

搞了一天,没有找到解决办法,用来你给的一个建议采用MultiByteToWideChar函数,得到的结果是正常的,但是始终不明白为什么送进MSCOMM空间的数字是unicode编码,接收出来的数据就自动变成了MBCS了!是在没办法理解,我想到了一个可能可以解释的理由是:因为串口默认一次发送的是8位(串口发送数据只有5,6,7,8几种方式),所以unicode的编码是不可能一次性发送过去的,所以中文编码两个字节实际上时分两次发送过去的,所以编写MSCOMM控件的人把汉字分为两个BYTE变量分别发送过去,而把汉字分为两个字节的时候是用MBCS编码方式分解的,所以收到的数据实际是两个BYTE数据(就分别是MBCS编码的高地位字节),而不是直接编码的数据。暂时只能这么理解了!!我的解决办法是:

myVar.Attach(m_ctrlComm.get_Input()); //我这个GetInput的返回值是VARIANT
safearray_inp = myVar;
len = safearray_inp.GetOneDimSize();
for(k = 0; k < len; k++)
{
safearray_inp.GetElement(&k, &rxdata);
if(rxdata > 127)
{
k++;
BYTE temp2;
safearray_inp.GetElement(&k, &temp2);
wchar_t temp1 = rxdata+temp2*256;
wchar_t tempu;
int len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)&temp1, 2, (LPWSTR)&tempu, 1);
strTemp += tempu;
}
else
{
strTemp += rxdata;
}
}

m_strEditRxData += strTemp;

通过第一字节数字是不是大于127,来判断是字符还是汉字(因为英文字符是用7位表示的所以小于128)。如果是汉字的话就把前两个字节提取出来,再转化为unicode编码!

   这样做的话,接收和发送中文和英文(ASCII)都没有问题!但是也有缺点,就是没有办法发送一些特殊字符(大于128的非ASCII特殊字符),但是基本上能满足应用!!


    谢谢诸位,暂时我只能这么理解了!!

#26


    在这里还要像大家说声抱歉,刚刚测试了一下!发现我忘记了一个比较严重的问题,就是初始化的时候有个选择接受方式函数put_InputMode,里面有设定以什么方式接收,我测试的时候一直是用二进制方式接收,所以汉字的话它会自动转化为MBCS编码方式发送出去(应该不是发送出去的问题,是接收MSCOMM接收到数据的时候的处理,会把它自动转化为两个字节的MBCS编码方式),如果设定为字符接收模式就没有什么问题,汉字接收时正常的!!也就是二进制模式本身也可以接收英文字符(因为英文字符的编码小于128),但是要接收汉字的话,就必须使用字符模式接收的话是正常的!!也就是上面的大侠说的用CString(m_ctrlComm.get_Input())接收时正常的(字符接收模式才可以用这种,我测试了一下,如果字符接收模式用myVar.Attach(m_ctrlComm.get_Input())的话软件会崩溃!!! )!!
    啊啊啊啊啊啊啊啊啊啊啊啊.........搞了一下午,估计就是这里出问题了!!现在已经都没有问题,抱歉了,一直是自己的问题~!!!!只是调试的时候根本没往哪方面想!!!
    多些大侠指点,虽然花了一下午时间,还是有蛮大收货的!!谢谢诸位!!!

#1


问题1:
COleSafeArray继承COleVariant,但又属于COleVariant的一个类型VT_ARRAY。
而COleSafeArray的每个元素又可以是COleVariant。
在网络环境中,数组是不能直接传递的,而必须将其包装成SafeArray,赋给COleVariant。
问题2:
你说的都对,只是编程习惯问题,两者是等效的。
问题3:
中文是接受过来了,但是你不能像下边这样 一个字节一个字节的取。因为汉字至少是2字节(根据编码不同)
        BYTE bt = *(char *)(rxdata+k);
        strTemp.Format(_T("%c"), bt);
        m_strEditRxData += strTemp;

直接CString(m_ctrlComm.get_Input())就应该有你要的结果了。

#2


引用 1 楼 ynb119 的回复:
问题1:
COleSafeArray继承COleVariant,但又属于COleVariant的一个类型VT_ARRAY。
而COleSafeArray的每个元素又可以是COleVariant。
在网络环境中,数组是不能直接传递的,而必须将其包装成SafeArray,赋给COleVariant。
问题2:
你说的都对,只是编程习惯问题,两者是等效的。
问题3:……

如果在网络环境中,数组是不能直接传递的,而必须将其包装成SafeArray,那发送程序的时候好像是用

m_ctrlComm.put_Output(COleVariant(m_strEditTxData));

为什么不是用COleSafeArray,那直接把m_ctrlComm.get_Input()的值赋给COleSafeArray也可以哦!!只是说一般这个函数的返回值是COleVariant,如果赋给COleSafeArray的话,C++又自动完成了类型转换!其实本质上和这两句差距不大:

myVar.Attach(m_ctrlComm.get_Input()); //我这个GetInput的返回值是VARIANT
safearray_inp = myVar;

是这个意思吗??

关于第三个问题,接收中文的方法的话,用CString(m_ctrlComm.get_Input())貌似不可以,接收到的全部是乱码????而且接收英文字符也有问题!!!!
这是改后的代码:

//接收中文字符
strTemp = CString(m_ctrlComm.get_Input());
m_strEditRxData += strTemp;

//接收二进制

/*myVar.Attach(m_ctrlComm.get_Input()); //我这个GetInput的返回值是VARIANT
safearray_inp = myVar;
len = safearray_inp.GetOneDimSize();
for(k = 0; k < len; k++)
{
safearray_inp.GetElement(&k, &rxdata);
strTemp += rxdata;
}
m_strEditRxData += strTemp;*/

#3


引用 1 楼 ynb119 的回复:
问题1:
COleSafeArray继承COleVariant,但又属于COleVariant的一个类型VT_ARRAY。
而COleSafeArray的每个元素又可以是COleVariant。
在网络环境中,数组是不能直接传递的,而必须将其包装成SafeArray,赋给COleVariant。
问题2:
你说的都对,只是编程习惯问题,两者是等效的。
问题3:……

谢谢啊!!!

#4


好问题!
加油!

#5


>>C++又自动完成了类型转换!其实本质上和这两句差距不大
你说的是对的。
>>用CString(m_ctrlComm.get_Input())貌似不可以,接收到的全部是乱码?
乱码可能是你发送方和接收方用的字符集不一样,比如说发送方是Mutibyte而接收方是UNICODE。

#6


#1 得分:0 回复于: 2013-01-08 17:05:36 
问题1:
COleSafeArray继承COleVariant,但又属于COleVariant的一个类型VT_ARRAY。
而COleSafeArray的每个元素又可以是COleVariant。
在网络环境中,数组是不能直接传递的,而必须将其包装成SafeArray,赋给COleVariant。
问题2:
你说的都对,只是编程习惯问题,两者是等效的。
问题3:
中文是接受过来了,但是你不能像下边这样 一个字节一个字节的取。因为汉字至少是2字节(根据编码不同)
        BYTE bt = *(char *)(rxdata+k);
        strTemp.Format(_T("%c"), bt);
        m_strEditRxData += strTemp;

直接CString(m_ctrlComm.get_Input())就应该有你要的结果了。

#7


引用 5 楼 ynb119 的回复:
>>C++又自动完成了类型转换!其实本质上和这两句差距不大
你说的是对的。
>>用CString(m_ctrlComm.get_Input())貌似不可以,接收到的全部是乱码?
乱码可能是你发送方和接收方用的字符集不一样,比如说发送方是Mutibyte而接收方是UNICODE。
 应该不会是字符集不一样吧!!!我是同一个程序生成的软件,两个软件直接对发!!或者发发送接收方短路自己发自己接,接到的也是乱码啊1!!!效果图如下:
几个关于MSCOMM控件串口通信编程的问题??

跟你说一下具体情况,就是发送单个字符貌似没有问题,但是一旦发送多个字符或者中文都是乱码!!!!

#8


引用 5 楼 ynb119 的回复:
>>C++又自动完成了类型转换!其实本质上和这两句差距不大
你说的是对的。
>>用CString(m_ctrlComm.get_Input())貌似不可以,接收到的全部是乱码?
乱码可能是你发送方和接收方用的字符集不一样,比如说发送方是Mutibyte而接收方是UNICODE。
还有一个问题要请教你如果用CString(m_ctrlComm.get_Input())应该会自动把接收到的数据(应该是COleVariant型)转化为CString类型,这样的直接用构造函数转换会不会有问题!!貌似COleVariant类型变量内部集成了一个联合体,可以存储各种变量,CString可以根据实际类型自动完成转换吗??谢谢啊!!!

#9


>>貌似COleVariant类型变量内部集成了一个联合体,可以存储各种变量,CString可以根据实际类型自动完成转换吗??谢谢啊!!!
一般来说是可以的(VT_BSTR类型)。但是对于VT_ARRAY我也没试过。可能真的不行。

试试下边的。

发送方  COleVariant myVar = CString("XXXXX");
接收方  CString(m_ctrlComm.get_Input());

#10


引用 9 楼 ynb119 的回复:
>>貌似COleVariant类型变量内部集成了一个联合体,可以存储各种变量,CString可以根据实际类型自动完成转换吗??谢谢啊!!!
一般来说是可以的(VT_BSTR类型)。但是对于VT_ARRAY我也没试过。可能真的不行。

试试下边的。

发送方  COleVariant myVar = CString("XXXXX");
接收方  CString(……

我发送大概是这样的啊!!!

UpdateData(true);
//发送字符
m_ctrlComm.put_Output(COleVariant(m_strEditTxData));

m_strEditTxData是CString类的变量!!也就是与文本框关联的变量!!!!这个程序原本发送英文字符时正常的!!!
就是把字符强制转化为COleVariant类啊!!1

#11


看来 CString(m_ctrlComm.get_Input());不太好用,这我也不知道怎么回事了。

VARIANT var =m_ctrlComm.get_Input();
 CString(var.bstrVal)
会是什么结果?

#12


编码方式不同?
Unicode与多字节 界面显示不同

#13


m_ctrlComm.get_Input() 取回来的是data 不是 string 吧?

#14


引用 11 楼 ynb119 的回复:
看来 CString(m_ctrlComm.get_Input());不太好用,这我也不知道怎么回事了。

VARIANT var =m_ctrlComm.get_Input();
 CString(var.bstrVal)
会是什么结果?

没有任何显示,也就是说接收到的数据不是存在bstrVal里面!!

#15


引用 12 楼 arpnet99 的回复:
编码方式不同?
Unicode与多字节 界面显示不同

能不能具体说清楚一点,我的软件环境是unicode,怎么解决这个问题!!谢谢!!!!

#16


引用 15 楼 li460135301 的回复:
引用 12 楼 arpnet99 的回复:编码方式不同?
Unicode与多字节 界面显示不同
能不能具体说清楚一点,我的软件环境是unicode,怎么解决这个问题!!谢谢!!!!

那很有可能是编码方式不同引起的。
需要用这个函数MultiByteToWideChar转换一下。
或者可以先直接把工程改为多字节测试一下,是不是这个问题。

#17


引用 16 楼 arpnet99 的回复:
引用 15 楼 li460135301 的回复:引用 12 楼 arpnet99 的回复:编码方式不同?
Unicode与多字节 界面显示不同
能不能具体说清楚一点,我的软件环境是unicode,怎么解决这个问题!!谢谢!!!!
那很有可能是编码方式不同引起的。
需要用这个函数MultiByteToWideChar转换一下。
或者可以先直接把工程改为多字节测试一……

工程切换到多字节依然是乱码!!用CString(m_ctrlComm.get_Input())
几个关于MSCOMM控件串口通信编程的问题??

#18


调试一下,看看m_ctrlComm.get_Input()中的数据是不是字符串,如果不是的话。是不能正常显示的。要先格式化一下。

#19


引用 18 楼 arpnet99 的回复:
调试一下,看看m_ctrlComm.get_Input()中的数据是不是字符串,如果不是的话。是不能正常显示的。要先格式化一下。

我如果发送一串字符的话,结果是字符串!您看下截图效果!!
一下是发送as两个英文字符的截图:
几个关于MSCOMM控件串口通信编程的问题??
收到的是乱码???转化为CString之后,但是在COleVariant或者COleSafeArray是正确的!

以下是发送“往”这个中文字符的截图:
几个关于MSCOMM控件串口通信编程的问题??
接收到在COleVariant中的值为cdf9,我专门查了一下这是“往”这个字的“GBK编码”就是国标码!所以传到CString中肯定是乱码!CString应该是用unicode编码的!并不是unicode编码!!!以下是往这个字的各种编码值:
几个关于MSCOMM控件串口通信编程的问题??


怎么解决这个问题呢????

#20


引用 18 楼 arpnet99 的回复:
调试一下,看看m_ctrlComm.get_Input()中的数据是不是字符串,如果不是的话。是不能正常显示的。要先格式化一下。

在MBCS环境下调试的结果一模一样!!!!

#21


‘as’ 那个 0 呢? (sz)标记

#22


引用 21 楼 schlafenhamster 的回复:
‘as’ 那个 0 呢? (sz)标记

是不是在CString转化为COleVariant时会自动把结束标志给截掉,也就是说这个数不通过串口发送过去!因为我们做串口一般发送的话还是不希望收到0 的吧!如果要发送二进制代码的话就用CByteArray来填充COleVariant,不用CString了!!!

#23


CString 到 BSTR 可能没有 0, 因为 BSTR 前面 有 长度。
你 这样 没有 0,就不是 字符串。 要 处理一下。

#24


引用 18 楼 arpnet99 的回复:
调试一下,看看m_ctrlComm.get_Input()中的数据是不是字符串,如果不是的话。是不能正常显示的。要先格式化一下。

我这里还调试了一下!发现这个现象,就是我发送“往”时发送的是这个字的unicode编码,这个应该没有错,因为我先把他存在COleVariant变量中查看了一下,COleVariant变量的值是5f80,也就是unciode编码值,但是接受到的数据不是unicode编码值,也就是说我把“往”放到COleVariant变量(5f80)放到MSCOMM空间中去发送,实际上发送的是cdf9(或者说至少接收到的是cdf9),也就是MBCS编码!!!而并不是接收到unicode编码的5f80,不知道什么问题!!!而5f80显然不是“往”的编码,所以接收到的数据就是乱码的!!

#25


引用 16 楼 arpnet99 的回复:
引用 15 楼 li460135301 的回复:引用 12 楼 arpnet99 的回复:编码方式不同?
Unicode与多字节 界面显示不同
能不能具体说清楚一点,我的软件环境是unicode,怎么解决这个问题!!谢谢!!!!
那很有可能是编码方式不同引起的。
需要用这个函数MultiByteToWideChar转换一下。
或者可以先直接把工程改为多字节测试一……

搞了一天,没有找到解决办法,用来你给的一个建议采用MultiByteToWideChar函数,得到的结果是正常的,但是始终不明白为什么送进MSCOMM空间的数字是unicode编码,接收出来的数据就自动变成了MBCS了!是在没办法理解,我想到了一个可能可以解释的理由是:因为串口默认一次发送的是8位(串口发送数据只有5,6,7,8几种方式),所以unicode的编码是不可能一次性发送过去的,所以中文编码两个字节实际上时分两次发送过去的,所以编写MSCOMM控件的人把汉字分为两个BYTE变量分别发送过去,而把汉字分为两个字节的时候是用MBCS编码方式分解的,所以收到的数据实际是两个BYTE数据(就分别是MBCS编码的高地位字节),而不是直接编码的数据。暂时只能这么理解了!!我的解决办法是:

myVar.Attach(m_ctrlComm.get_Input()); //我这个GetInput的返回值是VARIANT
safearray_inp = myVar;
len = safearray_inp.GetOneDimSize();
for(k = 0; k < len; k++)
{
safearray_inp.GetElement(&k, &rxdata);
if(rxdata > 127)
{
k++;
BYTE temp2;
safearray_inp.GetElement(&k, &temp2);
wchar_t temp1 = rxdata+temp2*256;
wchar_t tempu;
int len = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)&temp1, 2, (LPWSTR)&tempu, 1);
strTemp += tempu;
}
else
{
strTemp += rxdata;
}
}

m_strEditRxData += strTemp;

通过第一字节数字是不是大于127,来判断是字符还是汉字(因为英文字符是用7位表示的所以小于128)。如果是汉字的话就把前两个字节提取出来,再转化为unicode编码!

   这样做的话,接收和发送中文和英文(ASCII)都没有问题!但是也有缺点,就是没有办法发送一些特殊字符(大于128的非ASCII特殊字符),但是基本上能满足应用!!


    谢谢诸位,暂时我只能这么理解了!!

#26


    在这里还要像大家说声抱歉,刚刚测试了一下!发现我忘记了一个比较严重的问题,就是初始化的时候有个选择接受方式函数put_InputMode,里面有设定以什么方式接收,我测试的时候一直是用二进制方式接收,所以汉字的话它会自动转化为MBCS编码方式发送出去(应该不是发送出去的问题,是接收MSCOMM接收到数据的时候的处理,会把它自动转化为两个字节的MBCS编码方式),如果设定为字符接收模式就没有什么问题,汉字接收时正常的!!也就是二进制模式本身也可以接收英文字符(因为英文字符的编码小于128),但是要接收汉字的话,就必须使用字符模式接收的话是正常的!!也就是上面的大侠说的用CString(m_ctrlComm.get_Input())接收时正常的(字符接收模式才可以用这种,我测试了一下,如果字符接收模式用myVar.Attach(m_ctrlComm.get_Input())的话软件会崩溃!!! )!!
    啊啊啊啊啊啊啊啊啊啊啊啊.........搞了一下午,估计就是这里出问题了!!现在已经都没有问题,抱歉了,一直是自己的问题~!!!!只是调试的时候根本没往哪方面想!!!
    多些大侠指点,虽然花了一下午时间,还是有蛮大收货的!!谢谢诸位!!!