热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

MFC串口得到的数据怎么显示在listctrl上

串口收到一段数据,例如:---CD:19----ABCD:34----EFDG:12-----ABCD:20------JIOJ:15------。。。。。我如果想把ABCDEFDGABC
串口收到一段数据,例如:---CD:19----ABCD:34----EFDG:12-----ABCD:20------JIOJ:15------。。。。。
我如果想把ABCD  EFDG   ABCD  这三段分别在listctrl上显示,应该怎么做?


我的思路是,先把得到的字符串转换成数组,在判断是否是想要的数据,如果是,保存在另一个变量中;但是这样只能得到一段字符串,怎么分配到listctrl中呢?
我如果想得到这种效果应该怎么做,
第一列         第二列          第三列
ABCD:34    EFDG:12     ABCD :20
ABCD:20    EFDG:10     ABCD :30
ABCD:48    EFDG:19     ABCD :20

9 个解决方案

#1


实际工控项目,串口数据先存到数据库,再显示。

void CMainFrame::createList()
{
ctrlList.Create( WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SHOWSELALWAYS,
CRect(0,0,0,0), this, 1); //?? 不成功
ctrlList.SetExtendedStyle( LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT );

ctrlList.InsertColumn(0, L"开始时间", LVCFMT_CENTER, 120, 0 );
ctrlList.InsertColumn(1, L"结束时间", LVCFMT_CENTER, 120, 0 );
ctrlList.InsertColumn(2, L"管路号", LVCFMT_CENTER, 60, 0 );
ctrlList.InsertColumn(3, L"酒度", LVCFMT_CENTER, 60, 0 );
ctrlList.InsertColumn(4, L"设定值", LVCFMT_CENTER, 100, 0 );
ctrlList.InsertColumn(5, L"实际值", LVCFMT_CENTER, 100, 0 );
ctrlList.InsertColumn(6, L"实际体积", LVCFMT_CENTER, 100, 0 );
ctrlList.InsertColumn(7, L"开始温度", LVCFMT_CENTER, 60, 0 );
ctrlList.InsertColumn(8, L"结束温度", LVCFMT_CENTER, 60, 0 );
ctrlList.InsertColumn(9, L"产品名称", LVCFMT_CENTER, 120, 0 );
ctrlList.InsertColumn(10, L"产品批次", LVCFMT_CENTER, 120, 0 );
ctrlList.InsertColumn(11, L"R值", LVCFMT_CENTER, 100, 0 );
ctrlList.InsertColumn(12, L"脉冲总数", LVCFMT_CENTER, 120, 0 );

//配置数据源
SQLConfigDataSource( //?? 异常
                        NULL,
                        ODBC_ADD_DSN,
                        _T("Microsoft Access Driver (*.mdb)"),
                        _T("DSN=WS8DB\0DBQ=d:\\pj\\pj.mdb\0")
                        );

CDatabase data;
data.Open(_T("WS8DB"), //?? 异常
FALSE,
FALSE,
_T("DriverId=25;FIL=MS Access;MaxBufferSize=2048;PageTimeout=5;PWD=pj135246;UID=admin;")
);

CRecordset ds( &data );
ds.Open( CRecordset::snapshot, L"SELECT * FROM 历史记录 ORDER BY 开始时间 DESC" ); //??
CDBVariant dbv;
for( int i = 0 ; !ds.IsEOF(); i++ )
{
CString str;

ds.GetFieldValue(1, dbv);
if( dbv.m_dwType == DBVT_NULL )
str = L"";
else
str.Format( L"%i-%02i-%02i %02i:%02i", dbv.m_pdate->year, dbv.m_pdate->month, dbv.m_pdate->day, dbv.m_pdate->hour, dbv.m_pdate->minute ); 
int n = ctrlList.InsertItem( i, str );

ds.GetFieldValue(2, dbv);
if( dbv.m_dwType == DBVT_NULL )
str = L"";
else
str.Format( L"%i-%i-%i %i:%02i", dbv.m_pdate->year, dbv.m_pdate->month, dbv.m_pdate->day, dbv.m_pdate->hour, dbv.m_pdate->minute ); 
ctrlList.SetItemText( n, 1, str );

ds.GetFieldValue(3, dbv);
if( dbv.m_dwType == DBVT_NULL )
str = L"";
else
str.Format( L"%i", dbv.m_lVal );
ctrlList.SetItemText( n, 2, str );

ds.GetFieldValue(4, dbv);
if( dbv.m_dwType == DBVT_NULL )
str = L"";
else
str.Format( L"%0.1f", dbv.m_dblVal );
ctrlList.SetItemText( n, 3, str );

ds.GetFieldValue(5, dbv);
if( dbv.m_dwType == DBVT_NULL )
str = L"";
else
str.Format( L"%0.1f", dbv.m_dblVal );
ctrlList.SetItemText( n, 4, str );

ds.GetFieldValue(6, dbv);
if( dbv.m_dwType == DBVT_NULL )
str = L"";
else
str.Format( L"%0.1f", dbv.m_dblVal );
ctrlList.SetItemText( n, 5, str );

ds.GetFieldValue(7, dbv);
if( dbv.m_dwType == DBVT_NULL )
str = L"";
else
str.Format( L"%0.1f", dbv.m_dblVal );
ctrlList.SetItemText( n, 6, str );

ds.GetFieldValue(8, dbv);
if( dbv.m_dwType == DBVT_NULL )
str = L"";
else
str.Format( L"%0.1f", dbv.m_dblVal );
ctrlList.SetItemText( n, 7, str );

ds.GetFieldValue(9, dbv);
if( dbv.m_dwType == DBVT_NULL )
str = L"";
else
str.Format( L"%0.1f", dbv.m_dblVal );
ctrlList.SetItemText( n, 8, str );

ds.GetFieldValue(10, dbv);
ctrlList.SetItemText( n, 9, dbv.m_dwType == DBVT_NULL ? L"" :  *dbv.m_pstringW );

ds.GetFieldValue(11, dbv);
ctrlList.SetItemText( n, 10, dbv.m_dwType == DBVT_NULL ? L"" :  *dbv.m_pstringW );

ds.GetFieldValue(12, dbv);
if( dbv.m_dwType == DBVT_NULL )
str = L"";
else
str.Format( L"%0.4f", dbv.m_dblVal );
ctrlList.SetItemText( n, 11, str );

ds.GetFieldValue(13, dbv);
if( dbv.m_dwType == DBVT_NULL )
str = L"";
else
str.Format( L"%i", dbv.m_lVal );
ctrlList.SetItemText( n, 12, str );

ds.MoveNext();
}
ds.Close();
}

#2


引用 楼主 OTsino 的回复:
串口收到一段数据,例如:---CD:19----ABCD:34----EFDG:12-----ABCD:20------JIOJ:15------。。。。。
我如果想把ABCD  EFDG   ABCD  这三段分别在listctrl上显示,应该怎么做?


我的思路是,先把得到的字符串转换成数组,在判断是否是想要的数据,如果是,保存在另一个变量中;但是这样只能得到一段字符串,怎么分配到listctrl中呢?
我如果想得到这种效果应该怎么做,
第一列         第二列          第三列
ABCD:34    EFDG:12     ABCD :20
ABCD:20    EFDG:10     ABCD :30
ABCD:48    EFDG:19     ABCD :20

若是我,不会使用中间数组而直接操作,在收到第1条时插入一条记录,如:m_List1.InsertItem(item,内容1); 并初始化列号 I
再收到时,直接加入列中,如:m_List1.SetItemText(item,I,内容2); I增值直到完成此条记录。

#3


引用 1 楼 hhhh63 的回复:
实际工控项目,串口数据先存到数据库,再显示。

void CMainFrame::createList()
{
ctrlList.Create( WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SHOWSELALWAYS,
CRect(0,0,0,0), this, 1); //?? 不成功
ctrlList.SetExtendedStyle( LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT );

ctrlList.InsertColumn(0, L"开始时间", LVCFMT_CENTER, 120, 0 );
ctrlList.InsertColumn(1, L"结束时间", LVCFMT_CENTER, 120, 0 );
ctrlList.InsertColumn(2, L"管路号", LVCFMT_CENTER, 60, 0 );
ctrlList.InsertColumn(3, L"酒度", LVCFMT_CENTER, 60, 0 );
ctrlList.InsertColumn(4, L"设定值", LVCFMT_CENTER, 100, 0 );
ctrlList.InsertColumn(5, L"实际值", LVCFMT_CENTER, 100, 0 );
ctrlList.InsertColumn(6, L"实际体积", LVCFMT_CENTER, 100, 0 );
ctrlList.InsertColumn(7, L"开始温度", LVCFMT_CENTER, 60, 0 );
ctrlList.InsertColumn(8, L"结束温度", LVCFMT_CENTER, 60, 0 );
ctrlList.InsertColumn(9, L"产品名称", LVCFMT_CENTER, 120, 0 );
ctrlList.InsertColumn(10, L"产品批次", LVCFMT_CENTER, 120, 0 );
ctrlList.InsertColumn(11, L"R值", LVCFMT_CENTER, 100, 0 );
ctrlList.InsertColumn(12, L"脉冲总数", LVCFMT_CENTER, 120, 0 );

//配置数据源
SQLConfigDataSource( //?? 异常
                        NULL,
                        ODBC_ADD_DSN,
                        _T("Microsoft Access Driver (*.mdb)"),
                        _T("DSN=WS8DB\0DBQ=d:\\pj\\pj.mdb\0")
                        );

CDatabase data;
data.Open(_T("WS8DB"), //?? 异常
FALSE,
FALSE,
_T("DriverId=25;FIL=MS Access;MaxBufferSize=2048;PageTimeout=5;PWD=pj135246;UID=admin;")
);

CRecordset ds( &data );
ds.Open( CRecordset::snapshot, L"SELECT * FROM 历史记录 ORDER BY 开始时间 DESC" ); //??
CDBVariant dbv;
for( int i = 0 ; !ds.IsEOF(); i++ )
{
CString str;

ds.GetFieldValue(1, dbv);
if( dbv.m_dwType == DBVT_NULL )
str = L"";
else
str.Format( L"%i-%02i-%02i %02i:%02i", dbv.m_pdate->year, dbv.m_pdate->month, dbv.m_pdate->day, dbv.m_pdate->hour, dbv.m_pdate->minute ); 
int n = ctrlList.InsertItem( i, str );

ds.GetFieldValue(2, dbv);
if( dbv.m_dwType == DBVT_NULL )
str = L"";
else
str.Format( L"%i-%i-%i %i:%02i", dbv.m_pdate->year, dbv.m_pdate->month, dbv.m_pdate->day, dbv.m_pdate->hour, dbv.m_pdate->minute ); 
ctrlList.SetItemText( n, 1, str );

ds.GetFieldValue(3, dbv);
if( dbv.m_dwType == DBVT_NULL )
str = L"";
else
str.Format( L"%i", dbv.m_lVal );
ctrlList.SetItemText( n, 2, str );

ds.GetFieldValue(4, dbv);
if( dbv.m_dwType == DBVT_NULL )
str = L"";
else
str.Format( L"%0.1f", dbv.m_dblVal );
ctrlList.SetItemText( n, 3, str );

ds.GetFieldValue(5, dbv);
if( dbv.m_dwType == DBVT_NULL )
str = L"";
else
str.Format( L"%0.1f", dbv.m_dblVal );
ctrlList.SetItemText( n, 4, str );

ds.GetFieldValue(6, dbv);
if( dbv.m_dwType == DBVT_NULL )
str = L"";
else
str.Format( L"%0.1f", dbv.m_dblVal );
ctrlList.SetItemText( n, 5, str );

ds.GetFieldValue(7, dbv);
if( dbv.m_dwType == DBVT_NULL )
str = L"";
else
str.Format( L"%0.1f", dbv.m_dblVal );
ctrlList.SetItemText( n, 6, str );

ds.GetFieldValue(8, dbv);
if( dbv.m_dwType == DBVT_NULL )
str = L"";
else
str.Format( L"%0.1f", dbv.m_dblVal );
ctrlList.SetItemText( n, 7, str );

ds.GetFieldValue(9, dbv);
if( dbv.m_dwType == DBVT_NULL )
str = L"";
else
str.Format( L"%0.1f", dbv.m_dblVal );
ctrlList.SetItemText( n, 8, str );

ds.GetFieldValue(10, dbv);
ctrlList.SetItemText( n, 9, dbv.m_dwType == DBVT_NULL ? L"" :  *dbv.m_pstringW );

ds.GetFieldValue(11, dbv);
ctrlList.SetItemText( n, 10, dbv.m_dwType == DBVT_NULL ? L"" :  *dbv.m_pstringW );

ds.GetFieldValue(12, dbv);
if( dbv.m_dwType == DBVT_NULL )
str = L"";
else
str.Format( L"%0.4f", dbv.m_dblVal );
ctrlList.SetItemText( n, 11, str );

ds.GetFieldValue(13, dbv);
if( dbv.m_dwType == DBVT_NULL )
str = L"";
else
str.Format( L"%i", dbv.m_lVal );
ctrlList.SetItemText( n, 12, str );

ds.MoveNext();
}
ds.Close();
}

嗯,先保存到数据库中,再显示也是一种办法

#4


引用 2 楼 wxhxj0268 的回复:
Quote: 引用 楼主 OTsino 的回复:

串口收到一段数据,例如:---CD:19----ABCD:34----EFDG:12-----ABCD:20------JIOJ:15------。。。。。
我如果想把ABCD  EFDG   ABCD  这三段分别在listctrl上显示,应该怎么做?


我的思路是,先把得到的字符串转换成数组,在判断是否是想要的数据,如果是,保存在另一个变量中;但是这样只能得到一段字符串,怎么分配到listctrl中呢?
我如果想得到这种效果应该怎么做,
第一列         第二列          第三列
ABCD:34    EFDG:12     ABCD :20
ABCD:20    EFDG:10     ABCD :30
ABCD:48    EFDG:19     ABCD :20

若是我,不会使用中间数组而直接操作,在收到第1条时插入一条记录,如:m_List1.InsertItem(item,内容1); 并初始化列号 I
再收到时,直接加入列中,如:m_List1.SetItemText(item,I,内容2); I增值直到完成此条记录。

我用中间数组是为了截取数据中一段有用数据,直接插入一条记录,关键的地方就是这个内容1,内容2怎么是我想要的内容呢。现在很奇怪的是,如果收到的数据串很短,经过判断后能得到正确 的回复,如果收到的数据串很长,中间会有一部分数据丢失。

#5


void CScanChannelDlg::OnComm() 
{
// TODO: Add your control notification handler code here
 //   Sleep(1000);
VARIANT variant_inp;  
COleSafeArray safearray_inp;  
LONG len,k;  
BYTE rxdata[2048]; //设置BYTE数组 An 8-bit integerthat is not signed.  
CString strtemp;  
CString strchange1;
CString strchange2;
    char change[2048];
if(m_mscomm1.GetCommEvent()==2) //事件值为2表示接收缓冲区内有字符  
{ ////////以下你可以根据自己的通信协议加入处理代码  
variant_inp=m_mscomm1.GetInput(); //读缓冲区  
safearray_inp=variant_inp; //VARIANT型变量转换为ColeSafeArray型变量  
len=safearray_inp.GetOneDimSize(); //得到有效数据长度  
for(k=0;k safearray_inp.GetElement(&k,rxdata+k);//转换为BYTE型数组  
for(k=0;k {  
BYTE bt=*(char*)(rxdata+k); //字符型  
strtemp.Format("%c",bt); //将字符送入临时变量strtemp存放  
// MessageBox(strtemp,"strtemp");
strchange1+=strtemp;
}  
strncpy(change,(LPCTSTR)strchange1,sizeof(change));
int i,j;
// for(k=0;k // {
// strchange2.Format("%c",change[k]);
// m_editreceive+=strchange2;
// }

    for(i=0;i<(len-1);i++)
{
if(change[i]=='O' && change[i+1]=='p')
{
for(j=i;j<(len-1);j++)
{

if((change[j]=='-' && change[j+1]=='-')||(change[j]=='O' && change[j+1]=='K'))
        {
break;
}
                                         m_editreceive+=change[j];
}
}
}
}
UpdateData(FALSE);
}

#6


我不用串行通信组件,所以通信中也不会丢包,给一个Unicode转换函数,直接完成缓冲区转换,供参考:

// ANSI To UNCODE转换
CString CStringProc::AnsiToUnicode(char * szAnsi, int len)
{
CString str;
// ansi to unicode
//预转换,得到所需空间的大小
int wcsLen;
if(len>0)
wcsLen=len;
else
wcsLen= ::MultiByteToWideChar(CP_ACP, NULL, szAnsi, strlen(szAnsi), NULL, 0);
//分配空间要给'\0'留个空间,MultiByteToWideChar不会给'\0'空间
wchar_t* wszString = new wchar_t[wcsLen + 1];
//转换
::MultiByteToWideChar(CP_ACP, NULL, szAnsi, strlen(szAnsi), wszString, wcsLen);
//最后加上'\0'
wszString[wcsLen] = '\0'; // UNICODE字串
str=wszString;
delete wszString;
return str;
}

#7


长数据丢失应该是没存好,数据结构有问题

#8


结贴,问题解决了,方法没有错,在这里strncpy(change,(LPCTSTR)strchange1,sizeof(change));加个延迟就好了。感谢hhhh63和笨笨仔的热心回复。

#9


引用 7 楼 hhhh63 的回复:
长数据丢失应该是没存好,数据结构有问题
是的,在转换成数组的时候应该是没保存完整,加个延迟就OK了

推荐阅读
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Oracle分析函数first_value()和last_value()的用法及原理
    本文介绍了Oracle分析函数first_value()和last_value()的用法和原理,以及在查询销售记录日期和部门中的应用。通过示例和解释,详细说明了first_value()和last_value()的功能和不同之处。同时,对于last_value()的结果出现不一样的情况进行了解释,并提供了理解last_value()默认统计范围的方法。该文对于使用Oracle分析函数的开发人员和数据库管理员具有参考价值。 ... [详细]
  • 本文介绍了为什么要使用多进程处理TCP服务端,多进程的好处包括可靠性高和处理大量数据时速度快。然而,多进程不能共享进程空间,因此有一些变量不能共享。文章还提供了使用多进程实现TCP服务端的代码,并对代码进行了详细注释。 ... [详细]
  • 本文详细介绍了在ASP.NET中获取插入记录的ID的几种方法,包括使用SCOPE_IDENTITY()和IDENT_CURRENT()函数,以及通过ExecuteReader方法执行SQL语句获取ID的步骤。同时,还提供了使用这些方法的示例代码和注意事项。对于需要获取表中最后一个插入操作所产生的ID或马上使用刚插入的新记录ID的开发者来说,本文提供了一些有用的技巧和建议。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 如何在php中将mysql查询结果赋值给变量
    本文介绍了在php中将mysql查询结果赋值给变量的方法,包括从mysql表中查询count(学号)并赋值给一个变量,以及如何将sql中查询单条结果赋值给php页面的一个变量。同时还讨论了php调用mysql查询结果到变量的方法,并提供了示例代码。 ... [详细]
  • Oracle seg,V$TEMPSEG_USAGE与Oracle排序的关系及使用方法
    本文介绍了Oracle seg,V$TEMPSEG_USAGE与Oracle排序之间的关系,V$TEMPSEG_USAGE是V_$SORT_USAGE的同义词,通过查询dba_objects和dba_synonyms视图可以了解到它们的详细信息。同时,还探讨了V$TEMPSEG_USAGE的使用方法。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 深入理解Kafka服务端请求队列中请求的处理
    本文深入分析了Kafka服务端请求队列中请求的处理过程,详细介绍了请求的封装和放入请求队列的过程,以及处理请求的线程池的创建和容量设置。通过场景分析、图示说明和源码分析,帮助读者更好地理解Kafka服务端的工作原理。 ... [详细]
  • WhenIusepythontoapplythepymysqlmoduletoaddafieldtoatableinthemysqldatabase,itdo ... [详细]
author-avatar
杨芷寻找最真的自己
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有