大家救命,在用MSCOMM控件在一个按钮中实现发送和接收数据的问题。 我想在一个按钮响应函数中,发送一个数据包,然后等待一段时间后,再对接收的数据进行判断。我想用MSCOMM控件来实现,请问可不可以?我在发送数据后,用Sleep函数让线程等待一段时间,可是仍然不会产生CommEvent,要等到执行完这个按钮中所有的语句才会响应。请高手指点,谢谢! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 Windows中的程序是消息驱动的while(!GetMessage(...)){ switch(msg.message) { case ...: Function(); ... }}因此实际上没有中断来产生,一个按钮消息产生后只有消息Function()处理完成后才会获取到下一个消息,因此这种情况是正常的,不是代码问题 怎么用查询方式啊,能不能给出详细的代码,本人是个超级菜鸟。是不是不能用这个控件了,要用API函数实现或者用一个串口类啊。不过我还想用这个控件,不知道能不能行? 没用过MSCOMM,不过看了你的问题,说说我的想法.既然想等commevent发生再继续执行,不如加个mutex,互斥变量。 MZP互斥变量怎么加?怎么用?能不能给出代码? CSDN的高人都进来看看啊,我这个问题都发了2天了还没解决啊。 请问CreateMutexWaitForSingleObject在哪里创建,用的时候怎么用,能不能给出详细的代码。本人实在太菜了我的程序中的一部分如下:void CMovequipDlg::OnButton10() { // TODO: Add your control notification handler code here CMainFrame * pMainFrame = (CMainFrame*)AfxGetMainWnd(); CAutoMedView * pAutoMedView = (CAutoMedView*)pMainFrame->GetActiveView(); OnButton1();//对机器发送一条指令,然后它作出相应的动作后返回一条指令。 Sleep(1000); pAutoMedView->OnComm(); pAutoMedView->m_strReceiveData;//等待接收缓冲区里的数据,然后判断做下一步。这里主要是要接收到数据,然后才能最下一步。 OnButton2(); Sleep(2000);} http://cs.nju.edu.cn/yangxc/dcc2003.files/jszc-sub/comif-30.htm http://www.vczx.com/article/show.php?id=790换个控件试试 示例:初始化:bool CYourClass::OpenPort(){ if(m_Comm.GetPortOpen()) m_Comm.SetPortOpen(FALSE); m_Comm.SetCommPort(m_iPort); //选择com1 if( !m_Comm.GetPortOpen()) m_Comm.SetPortOpen(TRUE); //打开串口 else AfxMessageBox("cannot open serial port"); m_Comm.SetSettings(_T("1200,E,8,1")); //波特率1200,无校验,8个数据位,1个停止位 m_Comm.SetSThreshold(0); m_Comm.SetRThreshold(1); //参数1表示每当串口接收缓冲区中有多于或等于1个字符时将引发一个接收数据的OnComm事件 m_Comm.SetInputMode(1); m_Comm.SetInputLen(0); //设置当前接收区数据长度为0 return true;}发送:CByteArray bArryFrame;bArryFrame.Add(0x68);bArryFrame.Add(0x23);m_Comm.SetOutput(COleVariant(bArryFrame));接收:CByteArray m_RecFrameArray_All;(类中定义即可)void CYourClass::OnCommMscommCtrl() { // TODO: Add your control notification handler code here Sleep(300); VARIANT variant_inp; COleSafeArray safearray_inp; CString csDispString; LONG len; BYTE rxdata[2048]; //设置BYTE数组 An 8-bit integerthat is not signed. short ENO; CString strtemp; ENO=1;BYTE bt;CString csByte,csResult; if(1)//bReceive) { ENO=m_Comm.GetCommEvent(); if(ENO==2) //事件值为2表示接收缓冲区内有字符 { variant_inp = m_Comm.GetInput(); //读缓冲区 safearray_inp = variant_inp; //VARIANT型变量转换为ColeSafeArray型变量 len=safearray_inp.GetOneDimSize(); //得到有效数据长度 for(LONG iter=0;iter<len;iter++) { safearray_inp.GetElement(&iter,rxdata+iter); //转换为BYTE型数组 bt=*(char*)(rxdata+iter);m_RecFrameArray_All.Add(bt); strtemp.Format("%02X ",m_RecFrameArray_All.ElementAt(iter)); csResult+=strtemp; }} 如果是VC程序,建议不要用MSCOMM控件,自己用API实现,也没几句代码兼容性还好,不过我在网吧,没法给例子。 我的代码是这样写的:void CAutoMedView::OnInitialUpdate(){ m_Comm.SetCommPort(1); m_Comm.SetInBufferSize(1024); m_Comm.SetOutBufferSize(512); if(!m_Comm.GetPortOpen()) m_Comm.SetPortOpen(TRUE); m_Comm.SetInputMode(1); m_Comm.SetRThreshold(1); m_Comm.SetSettings("9600,n,8,1"); m_Comm.SetInputLen(0); m_Comm.GetInput(); m_Comm.SetEOFEnable(true);}////////////////////void CAutoMedView::OnOnCommMscomm() { // TODO: Add your control notification handler code here Sleep(3000); VARIANT m_Input1; COleSafeArray m_Input2; long length,i; BYTE data[1024]; CString str; if(m_Comm.GetCommEvent()==2) { m_Input1=m_Comm.GetInput(); m_Input2=m_Input1; length=m_Input2.GetOneDimSize(); for(i=0;i<length;i++) m_Input2.GetElement(&i,data+i); for(i=0;i<length;i++) { BYTE a=*(char*)(data+i); str.Format("%02X ",a); m_strReceiveData+=str; } } UpdateData(false);}////////////////////////////void CMovequipDlg::OnButton3() { // TODO: Add your control notification handler code here CMainFrame * pMainFrame = (CMainFrame*)AfxGetMainWnd(); CAutoMedView * pAutoMedView = (CAutoMedView*)pMainFrame->GetActiveView(); byte.RemoveAll(); UpdateData(TRUE); switch(m_nHprobe) { case 0: packet = "a5c5a040000000f5"; break; case 1: packet = "a5c5a140000000f5"; break; case 2: packet = "a5c5a240000000f5"; break; case 3: packet = "a5c5a340000000f5"; break; case 4: packet = "a5c5a440000000f5"; break; default: AfxMessageBox("请输入0--4之间的数"); return; } pAutoMedView->String2Hex(packet,byte); pAutoMedView->m_Comm.SetOutput(COleVariant(byte)); }//////////////////////////////////////////////////void CMovequipDlg::OnButton4() { // TODO: Add your control notification handler code here CMainFrame * pMainFrame = (CMainFrame*)AfxGetMainWnd(); CAutoMedView * pAutoMedView = (CAutoMedView*)pMainFrame->GetActiveView(); byte.RemoveAll(); UpdateData(TRUE); CString str; switch(m_nHsamplingpin) { case 0: packet = "a5c7a140000000f5"; break; case 1: packet = "a5c7a240000000f5"; break; default: AfxMessageBox("请输入0--1之间的数"); return; } pAutoMedView->String2Hex(packet,byte); pAutoMedView->m_Comm.SetOutput(COleVariant(byte)); }void CMovequipDlg::OnButton10() { // TODO: Add your control notification handler code here CMainFrame * pMainFrame = (CMainFrame*)AfxGetMainWnd(); CAutoMedView * pAutoMedView = (CAutoMedView*)pMainFrame->GetActiveView(); OnButton3(); Sleep(2000); pAutoMedView->OnComm();//在这里对收到的数据进行判断,然后再进行其它数据的发送。可是进入 OnOnCommMscomm()函数它并不执行if(m_Comm.GetCommEvent()==2)这个判断里的内容,不管Sleep多久。 OnButton4(); UpdateData(false);} void CMovequipDlg::OnButton10() { OnButton3(); Sleep(2000);}你在事件处理函数中调用事件处理函数.OnButtton3是不会执行的.你可以跟踪一下 wy311216我的OnButton3()里实际也是发送数据的,我跟踪了,实际实际是执行的,及时把他换成,OnButton3()里的语句也没有意义,我现在主要想解决的是,在一个按钮里,同时发送然后等下微机处理完数据后,在接收数据,对其判断,然后再发数据。 BOOL CComTestDlg::ComInitialize(int i){ if(m_com.GetPortOpen()) { //若有开启的COM口则关闭 m_com.SetPortOpen(FALSE); } m_com.SetCommPort(i); if (!m_com.GetPortOpen()) { //打开串口 m_com.SetPortOpen(TRUE); } //波特率9600,无校验,8个数据位,1个停止位 m_com.SetSettings("19200,n,8,1"); // 以二进制方式检取数据,参数取0数据以文字形式取回 m_com.SetInputMode(1); //参数1表示每当串口接收缓冲区中有多于或等于1个字符时将引发一个接收数据的OnComm事件 m_com.SetRThreshold(1); //先预读缓冲区以清除残留数据 m_com.GetInput(); return TRUE;}void CComTestDlg::OnButtonopencom() { UpdateData(TRUE); if(!(m_comValue == "1" || m_comValue == "2") ) { MessageBox("请选择需要打开的COM口"); return; } ComInitialize(atoi(m_comValue)); m_openBtn.EnableWindow(FALSE); m_sendBtn.EnableWindow(TRUE); m_importBtn.EnableWindow(TRUE);}void CComTestDlg::OnClose() { if(m_com.GetPortOpen()) { //若有开启的COM口则关闭 m_com.SetPortOpen(FALSE); } DestroyWindow(); }void CComTestDlg::OnOnCommMscomm() { CListCtrl *preturnListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST2); CListCtrl *pdataListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST1); //定义VARIANT型变量 VARIANT m_input1; //定义COleSafeArray型变量 COleSafeArray m_input2; int length; LONG i; //定义字节数组 BYTE data[128],datahead; CString str,str1; //接收缓冲区内字符 if(m_com.GetCommEvent()== 2) { m_com.SetInputLen(1); //从缓冲区读数据 m_input1=m_com.GetInput(); //将VARIANT型变量转换为ColeSafeArray型变量 m_input2=m_input1; //将数据转换为BYTE型数组 for(i=0;i< 1;i++) m_input2.GetElement(&i,data+i); datahead=data[0]; //传送出的数据得到正确响应,终止定时器,删除第一个数据 if(datahead==0xA5) { KillTimer(1); pdataListCtrl->DeleteItem(0); Send(); } //重发第一个数据 else if(datahead==0xA6)//发送出去的数据错误,重新发送. { Send(); } else if(datahead==0x5A)//发送过来的命令 { m_com.SetInputLen(1); m_input1=m_com.GetInput(); m_input2=m_input1; for(i=0;i< 1;i++) m_input2.GetElement(&i,data+i); length=data[0]; m_com.SetInputLen(length); //从缓冲区读数据 //Sleep(50); m_input1=m_com.GetInput(); //将VARIANT型变量转换为ColeSafeArray型变量 m_input2=m_input1; //将数据转换为BYTE型数组 for(i=0;i< length;i++) m_input2.GetElement(&i,data+i); //m_data1=data[1];//sno //m_data2=data[2]+1;//bno BYTE CHKRESULT = 0; for(i=0;i<length;i++)//校验数据的正确与否。CHK+SNO+BNO+BARCODE[1]+BARCODE[N] { CHKRESULT+=data[i]; } if(CHKRESULT==0) { //preturnListCtrl添加数据 CString strBoxNo,strReaderNo,strData; strBoxNo.Format("%d",data[1]); strReaderNo.Format("%d",data[2]+1); strData.Format("0x%02X",data[3]); int i = preturnListCtrl->GetItemCount(); pdataListCtrl->InsertItem(LVIF_TEXT|LVIF_STATE,i,strBoxNo,0,LVIS_SELECTED,0,0); pdataListCtrl->SetItemText(i,1,strReaderNo); pdataListCtrl->SetItemText(i,2,strData); } } else if(datahead==0xA7) { } } }//将CString转为CByteArrayvoid CComTestDlg::String2Hex(CString str, CByteArray &senddata){ int hexdata,lowhexdata; int hexdatalen=0; int len=str.GetLength(); senddata.SetSize(len/2); for(int i=0;i<len;) { char lstr,hstr=str[i]; if(hstr==' ') { i++; continue; } i++; if(i>=len) break; lstr=str[i]; hexdata=ConvertHexChar(hstr); lowhexdata=ConvertHexChar(lstr); if((hexdata==16)||(lowhexdata==16)) break; else hexdata=hexdata*16+lowhexdata; i++; senddata[hexdatalen]=(char)hexdata; hexdatalen++; }}//这是一个将字符转换为相应的十六进制值的函数//功能:若是在0-F之间的字符,则转换为相应的十六进制字符,否则返回-1char CComTestDlg::ConvertHexChar(char ch) { if((ch>='0')&&(ch<='9')) return ch-0x30; else if((ch>='A')&&(ch<='F')) return ch-'A'+10; else if((ch>='a')&&(ch<='f')) return ch-'a'+10; else return (-1);}void CComTestDlg::SendData(CString str,int sno,int bno)//向串接器发送命令{ CByteArray hexdata; CString str1 = ""; CString str2 = ""; CString str3 = ""; int CMD[5]; int result = 0; int check = 0; int header = 0x5A; int len = str.GetLength(); BYTE data[128]; for (int i=0; i<len; i++) { data[i] = str.GetAt(i); result = result + data[i]; str1.Format("%02X", data[i]); //$ str2 += str1; } str3 = str2; //计算校验码 check = 256-(sno + bno + result - 1)%256; CMD[0] = 0x5A; CMD[1] = len + 3; CMD[2] = check; CMD[3] = sno; CMD[4] = bno - 1; str1 = ""; str2 = ""; for(i=0;i<5;i++) { str1.Format("%02X",CMD[i]); //$ str2 += str1; } //向串口发送数据 str = str2 + str3; String2Hex(str,hexdata); m_com.SetOutput(COleVariant(hexdata)); //发送数据}//发送数据到串口void CComTestDlg::OnSend() { Send();}//发送数据到串口void CComTestDlg::Send(){ //从datalist中得到要发送的数据发送出去 CString strBoxNo; CString strReaderNo; CString strData; int BoxNo; int ReaderNo; CListCtrl *pdataListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST1); if (pdataListCtrl->GetItemCount() <= 0) { //MessageBox("没有数据"); return; } strBoxNo = pdataListCtrl->GetItemText(0,0); strReaderNo = pdataListCtrl->GetItemText(0,1); strData = pdataListCtrl->GetItemText(0,2); BoxNo = atoi(strBoxNo.GetBuffer(0)); ReaderNo = atoi(strReaderNo.GetBuffer(0)); SendData(strData, BoxNo, ReaderNo); //启动定时器 SetTimer(1,20000,NULL);}void CComTestDlg::OnTimer(UINT nIDEvent) { switch(nIDEvent) { case 1: Send(); break; case 2: ; }//CDialog::OnTimer(nIDEvent);}void CComTestDlg::OnClear() { //CListCtrl *preturnListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST2); //preturnListCtrl->DeleteAllItems(); MessageBox("hello");}void CComTestDlg::OnImport() { CListCtrl *pdataListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST1); pdataListCtrl->DeleteAllItems(); CString szLine = ""; CString strBoxNo = ""; CString strReaderNo = ""; CString strData = ""; CFileFind find; if(!find.FindFile(".//data.txt")) { MessageBox("没有可导入的数据文件"); return; } CStdioFile file; file.Open("data.txt",CFile::modeRead); while(file.ReadString(szLine)) { if(szLine != "") { CString str = ""; szLine.TrimLeft(); szLine.TrimRight(); for(int i=0; i<szLine.GetLength(); i++) { str = szLine.Mid(i,1); if(str == " ") { strBoxNo = szLine.Left(i); szLine = szLine.Mid(i); szLine.TrimLeft(); szLine.TrimRight(); break; } } if(szLine != "") { CString str1 = ""; for(int k=0; k<szLine.GetLength(); k++) { str1 = szLine.Mid(k,1); if(str1 == " ") { strReaderNo = szLine.Left(k); szLine = szLine.Mid(k); szLine.TrimLeft(); szLine.TrimRight(); break; } } if(szLine != "") { strData = szLine; } } if(strBoxNo=="" || strReaderNo=="" || strData == "") { continue; } int j = pdataListCtrl->GetItemCount(); pdataListCtrl->InsertItem(LVIF_TEXT|LVIF_STATE,j,strBoxNo,0,LVIS_SELECTED,0,0); pdataListCtrl->SetItemText(j,1,strReaderNo); pdataListCtrl->SetItemText(j,2,strData); strBoxNo = ""; strReaderNo = ""; strData = ""; } }} pAutoMedView->OnComm();虽然你触发了串口事件,但是和接收到外部数据触发的串口事件是两个不同的线程.所以你在OnButton10里面接收数据是不可能收到的.你得在OnComm事件处理里面接收 pAutoMedView->OnComm();这个我也知道,不过是想检验一下在按钮执行的过程中是否能响应OnComm事件处理,我也说过了它根本不会去执行if(m_Comm.GetCommEvent()==2) 里面的东东。 程序并没有错, ComEvReceive也可能发生了(如果通信连接正确的话.),怀疑测试过程中发送的数据太少,当你点击void CAutoMedView::OnOnCommMscomm() 所对应的工具或菜单时发送已经完成,此时收到的是ComEvEOF事件.建议1:把m_Comm.SetPortOpen(TRUE);放到OnOnCommMscomm()函数中;建议2:对m_Comm.GetCommEvent()==2返回的事件进行逐一判断,这应该是好习惯. 求 WinRing0.sys 的源代码!!!!!!!!! 字符串里面有双引号报错,怎么办。。。 请问如何实现在已打开的网页上自动输入帐号密码? 请问这种界面用MFC是怎么弄出来的啊?我找不到它所对应的函数啊 ButtonDown时如何判断鼠标位置在BUTTON上 服务里面为何启动不了其他程序?急~~~~~~~~~~~ 如何根据路径来判断文件夹是否共享 服务启动问题 Recordset建立之后如何高效地把数据取出并显示在列表中? 请教:在一个框架中进行view的切换,切换时先删除当前view,然后动态创建新的view,结果删除不掉! 在线等待,急!散分(100!) 求MSChart控件的资料
while(!GetMessage(...))
{
switch(msg.message)
{
case ...:
Function();
...
}
}
因此实际上没有中断来产生,一个按钮消息产生后只有消息Function()处理完成后才会获取到下一个消息,因此这种情况是正常的,不是代码问题
既然想等commevent发生再继续执行,不如加个mutex,互斥变量。
CreateMutex
WaitForSingleObject
在哪里创建,用的时候怎么用,能不能给出详细的代码。本人实在太菜了
我的程序中的一部分如下:void CMovequipDlg::OnButton10()
{
// TODO: Add your control notification handler code here
CMainFrame * pMainFrame = (CMainFrame*)AfxGetMainWnd();
CAutoMedView * pAutoMedView = (CAutoMedView*)pMainFrame->GetActiveView();
OnButton1();//对机器发送一条指令,然后它作出相应的动作后返回一条指令。
Sleep(1000);
pAutoMedView->OnComm();
pAutoMedView->m_strReceiveData;//等待接收缓冲区里的数据,然后判断做下一步。这里主要是要接收到数据,然后才能最下一步。
OnButton2();
Sleep(2000);
}
换个控件试试
初始化:
bool CYourClass::OpenPort()
{
if(m_Comm.GetPortOpen())
m_Comm.SetPortOpen(FALSE);
m_Comm.SetCommPort(m_iPort); //选择com1
if( !m_Comm.GetPortOpen())
m_Comm.SetPortOpen(TRUE); //打开串口
else
AfxMessageBox("cannot open serial port"); m_Comm.SetSettings(_T("1200,E,8,1")); //波特率1200,无校验,8个数据位,1个停止位
m_Comm.SetSThreshold(0);
m_Comm.SetRThreshold(1); //参数1表示每当串口接收缓冲区中有多于或等于1个字符时将引发一个接收数据的OnComm事件
m_Comm.SetInputMode(1);
m_Comm.SetInputLen(0); //设置当前接收区数据长度为0
return true;
}
发送:
CByteArray bArryFrame;
bArryFrame.Add(0x68);
bArryFrame.Add(0x23);
m_Comm.SetOutput(COleVariant(bArryFrame));接收:
CByteArray m_RecFrameArray_All;(类中定义即可)
void CYourClass::OnCommMscommCtrl()
{
// TODO: Add your control notification handler code here
Sleep(300); VARIANT variant_inp;
COleSafeArray safearray_inp;
CString csDispString;
LONG len;
BYTE rxdata[2048]; //设置BYTE数组 An 8-bit integerthat is not signed.
short ENO;
CString strtemp;
ENO=1;BYTE bt;CString csByte,csResult;
if(1)//bReceive)
{
ENO=m_Comm.GetCommEvent();
if(ENO==2) //事件值为2表示接收缓冲区内有字符
{
variant_inp = m_Comm.GetInput(); //读缓冲区
safearray_inp = variant_inp; //VARIANT型变量转换为ColeSafeArray型变量
len=safearray_inp.GetOneDimSize(); //得到有效数据长度
for(LONG iter=0;iter<len;iter++)
{
safearray_inp.GetElement(&iter,rxdata+iter); //转换为BYTE型数组 bt=*(char*)(rxdata+iter);m_RecFrameArray_All.Add(bt);
strtemp.Format("%02X ",m_RecFrameArray_All.ElementAt(iter));
csResult+=strtemp;
}
}
void CAutoMedView::OnInitialUpdate()
{
m_Comm.SetCommPort(1);
m_Comm.SetInBufferSize(1024);
m_Comm.SetOutBufferSize(512);
if(!m_Comm.GetPortOpen())
m_Comm.SetPortOpen(TRUE);
m_Comm.SetInputMode(1);
m_Comm.SetRThreshold(1);
m_Comm.SetSettings("9600,n,8,1");
m_Comm.SetInputLen(0);
m_Comm.GetInput();
m_Comm.SetEOFEnable(true);}
////////////////////
void CAutoMedView::OnOnCommMscomm()
{
// TODO: Add your control notification handler code here
Sleep(3000);
VARIANT m_Input1;
COleSafeArray m_Input2;
long length,i;
BYTE data[1024];
CString str;
if(m_Comm.GetCommEvent()==2)
{
m_Input1=m_Comm.GetInput();
m_Input2=m_Input1;
length=m_Input2.GetOneDimSize();
for(i=0;i<length;i++)
m_Input2.GetElement(&i,data+i);
for(i=0;i<length;i++)
{
BYTE a=*(char*)(data+i);
str.Format("%02X ",a);
m_strReceiveData+=str;
}
}
UpdateData(false);
}
////////////////////////////
void CMovequipDlg::OnButton3()
{
// TODO: Add your control notification handler code here
CMainFrame * pMainFrame = (CMainFrame*)AfxGetMainWnd();
CAutoMedView * pAutoMedView = (CAutoMedView*)pMainFrame->GetActiveView();
byte.RemoveAll();
UpdateData(TRUE);
switch(m_nHprobe)
{
case 0:
packet = "a5c5a040000000f5";
break;
case 1:
packet = "a5c5a140000000f5";
break;
case 2:
packet = "a5c5a240000000f5";
break;
case 3:
packet = "a5c5a340000000f5";
break;
case 4:
packet = "a5c5a440000000f5";
break;
default:
AfxMessageBox("请输入0--4之间的数");
return;
}
pAutoMedView->String2Hex(packet,byte);
pAutoMedView->m_Comm.SetOutput(COleVariant(byte));
}
//////////////////////////////////////////////////
void CMovequipDlg::OnButton4()
{
// TODO: Add your control notification handler code here
CMainFrame * pMainFrame = (CMainFrame*)AfxGetMainWnd();
CAutoMedView * pAutoMedView = (CAutoMedView*)pMainFrame->GetActiveView();
byte.RemoveAll();
UpdateData(TRUE);
CString str;
switch(m_nHsamplingpin)
{
case 0:
packet = "a5c7a140000000f5";
break;
case 1:
packet = "a5c7a240000000f5";
break;
default:
AfxMessageBox("请输入0--1之间的数");
return;
}
pAutoMedView->String2Hex(packet,byte);
pAutoMedView->m_Comm.SetOutput(COleVariant(byte));
}
void CMovequipDlg::OnButton10()
{
// TODO: Add your control notification handler code here
CMainFrame * pMainFrame = (CMainFrame*)AfxGetMainWnd();
CAutoMedView * pAutoMedView = (CAutoMedView*)pMainFrame->GetActiveView();
OnButton3();
Sleep(2000);
pAutoMedView->OnComm();
//在这里对收到的数据进行判断,然后再进行其它数据的发送。可是进入 OnOnCommMscomm()函数它并不执行if(m_Comm.GetCommEvent()==2)这个判断里的内容,不管Sleep多久。
OnButton4();
UpdateData(false);
}
{
OnButton3();
Sleep(2000);
}
你在事件处理函数中调用事件处理函数.OnButtton3是不会执行的.你可以跟踪一下
我的OnButton3()里实际也是发送数据的,我跟踪了,实际实际是执行的,及时把他换成,OnButton3()里的语句也没有意义,我现在主要想解决的是,在一个按钮里,同时发送然后等下微机处理完数据后,在接收数据,对其判断,然后再发数据。
{
if(m_com.GetPortOpen())
{
//若有开启的COM口则关闭
m_com.SetPortOpen(FALSE);
}
m_com.SetCommPort(i);
if (!m_com.GetPortOpen())
{
//打开串口
m_com.SetPortOpen(TRUE);
}
//波特率9600,无校验,8个数据位,1个停止位
m_com.SetSettings("19200,n,8,1");
// 以二进制方式检取数据,参数取0数据以文字形式取回
m_com.SetInputMode(1);
//参数1表示每当串口接收缓冲区中有多于或等于1个字符时将引发一个接收数据的OnComm事件
m_com.SetRThreshold(1);
//先预读缓冲区以清除残留数据
m_com.GetInput();
return TRUE;
}void CComTestDlg::OnButtonopencom()
{
UpdateData(TRUE);
if(!(m_comValue == "1" || m_comValue == "2") )
{
MessageBox("请选择需要打开的COM口");
return;
}
ComInitialize(atoi(m_comValue));
m_openBtn.EnableWindow(FALSE);
m_sendBtn.EnableWindow(TRUE);
m_importBtn.EnableWindow(TRUE);
}void CComTestDlg::OnClose()
{
if(m_com.GetPortOpen())
{
//若有开启的COM口则关闭
m_com.SetPortOpen(FALSE);
}
DestroyWindow();
}void CComTestDlg::OnOnCommMscomm()
{
CListCtrl *preturnListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST2);
CListCtrl *pdataListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST1);
//定义VARIANT型变量
VARIANT m_input1;
//定义COleSafeArray型变量
COleSafeArray m_input2;
int length;
LONG i;
//定义字节数组
BYTE data[128],datahead;
CString str,str1;
//接收缓冲区内字符
if(m_com.GetCommEvent()== 2)
{
m_com.SetInputLen(1);
//从缓冲区读数据
m_input1=m_com.GetInput();
//将VARIANT型变量转换为ColeSafeArray型变量
m_input2=m_input1;
//将数据转换为BYTE型数组
for(i=0;i< 1;i++)
m_input2.GetElement(&i,data+i);
datahead=data[0];
//传送出的数据得到正确响应,终止定时器,删除第一个数据
if(datahead==0xA5)
{
KillTimer(1);
pdataListCtrl->DeleteItem(0);
Send();
}
//重发第一个数据
else if(datahead==0xA6)//发送出去的数据错误,重新发送.
{
Send();
}
else if(datahead==0x5A)//发送过来的命令
{
m_com.SetInputLen(1);
m_input1=m_com.GetInput();
m_input2=m_input1;
for(i=0;i< 1;i++)
m_input2.GetElement(&i,data+i);
length=data[0];
m_com.SetInputLen(length);
//从缓冲区读数据
//Sleep(50);
m_input1=m_com.GetInput();
//将VARIANT型变量转换为ColeSafeArray型变量
m_input2=m_input1;
//将数据转换为BYTE型数组
for(i=0;i< length;i++)
m_input2.GetElement(&i,data+i);
//m_data1=data[1];//sno
//m_data2=data[2]+1;//bno
BYTE CHKRESULT = 0;
for(i=0;i<length;i++)//校验数据的正确与否。CHK+SNO+BNO+BARCODE[1]+BARCODE[N]
{
CHKRESULT+=data[i];
}
if(CHKRESULT==0)
{
//preturnListCtrl添加数据
CString strBoxNo,strReaderNo,strData;
strBoxNo.Format("%d",data[1]);
strReaderNo.Format("%d",data[2]+1);
strData.Format("0x%02X",data[3]);
int i = preturnListCtrl->GetItemCount();
pdataListCtrl->InsertItem(LVIF_TEXT|LVIF_STATE,i,strBoxNo,0,LVIS_SELECTED,0,0);
pdataListCtrl->SetItemText(i,1,strReaderNo);
pdataListCtrl->SetItemText(i,2,strData);
}
}
else if(datahead==0xA7)
{
}
}
}//将CString转为CByteArray
void CComTestDlg::String2Hex(CString str, CByteArray &senddata)
{
int hexdata,lowhexdata;
int hexdatalen=0;
int len=str.GetLength();
senddata.SetSize(len/2);
for(int i=0;i<len;)
{
char lstr,hstr=str[i];
if(hstr==' ')
{
i++;
continue;
}
i++;
if(i>=len)
break;
lstr=str[i];
hexdata=ConvertHexChar(hstr);
lowhexdata=ConvertHexChar(lstr);
if((hexdata==16)||(lowhexdata==16))
break;
else
hexdata=hexdata*16+lowhexdata;
i++;
senddata[hexdatalen]=(char)hexdata;
hexdatalen++;
}
}//这是一个将字符转换为相应的十六进制值的函数
//功能:若是在0-F之间的字符,则转换为相应的十六进制字符,否则返回-1
char CComTestDlg::ConvertHexChar(char ch)
{
if((ch>='0')&&(ch<='9'))
return ch-0x30;
else if((ch>='A')&&(ch<='F'))
return ch-'A'+10;
else if((ch>='a')&&(ch<='f'))
return ch-'a'+10;
else return (-1);
}void CComTestDlg::SendData(CString str,int sno,int bno)//向串接器发送命令
{
CByteArray hexdata;
CString str1 = "";
CString str2 = "";
CString str3 = "";
int CMD[5];
int result = 0;
int check = 0;
int header = 0x5A;
int len = str.GetLength();
BYTE data[128];
for (int i=0; i<len; i++)
{
data[i] = str.GetAt(i);
result = result + data[i];
str1.Format("%02X", data[i]); //$
str2 += str1;
}
str3 = str2;
//计算校验码
check = 256-(sno + bno + result - 1)%256;
CMD[0] = 0x5A;
CMD[1] = len + 3;
CMD[2] = check;
CMD[3] = sno;
CMD[4] = bno - 1; str1 = "";
str2 = "";
for(i=0;i<5;i++)
{
str1.Format("%02X",CMD[i]); //$
str2 += str1;
}
//向串口发送数据
str = str2 + str3;
String2Hex(str,hexdata);
m_com.SetOutput(COleVariant(hexdata)); //发送数据
}//发送数据到串口
void CComTestDlg::OnSend()
{
Send();
}//发送数据到串口
void CComTestDlg::Send()
{
//从datalist中得到要发送的数据发送出去
CString strBoxNo;
CString strReaderNo;
CString strData;
int BoxNo;
int ReaderNo;
CListCtrl *pdataListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST1);
if (pdataListCtrl->GetItemCount() <= 0)
{
//MessageBox("没有数据");
return;
}
strBoxNo = pdataListCtrl->GetItemText(0,0);
strReaderNo = pdataListCtrl->GetItemText(0,1);
strData = pdataListCtrl->GetItemText(0,2);
BoxNo = atoi(strBoxNo.GetBuffer(0));
ReaderNo = atoi(strReaderNo.GetBuffer(0));
SendData(strData, BoxNo, ReaderNo);
//启动定时器
SetTimer(1,20000,NULL);
}void CComTestDlg::OnTimer(UINT nIDEvent)
{
switch(nIDEvent)
{
case 1:
Send();
break;
case 2:
;
}
//CDialog::OnTimer(nIDEvent);
}void CComTestDlg::OnClear()
{
//CListCtrl *preturnListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST2);
//preturnListCtrl->DeleteAllItems();
MessageBox("hello");
}
void CComTestDlg::OnImport()
{
CListCtrl *pdataListCtrl = (CListCtrl*)GetDlgItem(IDC_LIST1);
pdataListCtrl->DeleteAllItems();
CString szLine = "";
CString strBoxNo = "";
CString strReaderNo = "";
CString strData = "";
CFileFind find;
if(!find.FindFile(".//data.txt"))
{
MessageBox("没有可导入的数据文件");
return;
}
CStdioFile file;
file.Open("data.txt",CFile::modeRead);
while(file.ReadString(szLine))
{
if(szLine != "")
{
CString str = "";
szLine.TrimLeft();
szLine.TrimRight();
for(int i=0; i<szLine.GetLength(); i++)
{
str = szLine.Mid(i,1);
if(str == " ")
{
strBoxNo = szLine.Left(i);
szLine = szLine.Mid(i);
szLine.TrimLeft();
szLine.TrimRight();
break;
}
}
if(szLine != "")
{
CString str1 = "";
for(int k=0; k<szLine.GetLength(); k++)
{
str1 = szLine.Mid(k,1);
if(str1 == " ")
{
strReaderNo = szLine.Left(k);
szLine = szLine.Mid(k);
szLine.TrimLeft();
szLine.TrimRight();
break;
}
}
if(szLine != "")
{
strData = szLine;
}
}
if(strBoxNo=="" || strReaderNo=="" || strData == "")
{
continue;
}
int j = pdataListCtrl->GetItemCount(); pdataListCtrl->InsertItem(LVIF_TEXT|LVIF_STATE,j,strBoxNo,0,LVIS_SELECTED,0,0);
pdataListCtrl->SetItemText(j,1,strReaderNo);
pdataListCtrl->SetItemText(j,2,strData);
strBoxNo = "";
strReaderNo = "";
strData = "";
}
}
}
虽然你触发了串口事件,但是和接收到外部数据触发的串口事件是两个不同的线程.所以你在OnButton10里面接收数据是不可能收到的.你得在OnComm事件处理里面接收
这个我也知道,不过是想检验一下在按钮执行的过程中是否能响应OnComm事件处理,我也说过了它根本不会去执行if(m_Comm.GetCommEvent()==2) 里面的东东。