本文分享了作者在实际项目中使用定时器的心得和体会,包括定时器的工作原理、应用场景以及常见问题的解决方法。适合开发者参考学习。
在`ClassWizard`中响应ID为~Dlg中的WM_TIMER消息。使用`SetTimer(nIDEvent,time,NULL)`来建立一个定时器,并用`KillTimer(nIDEvent)`函数关闭该定时器。接下来,可以通过响应ON_WM_TIMER消息,在定时器完成一次计时后处理相关程序事件。具体实现方式如下:
```cpp
void CTimeDlg::OnTimer(UINT nIDEvent)
{
if (nIDEvent == 1000) { // 定时时间为5秒
// 处理相应事件
} else if (nIDEvent == 1001) { // 定时时间为10秒
// 处理相应事件
}
CDialog::OnTimer(nIDEvent);
}
```
下面是一个串口通信定时检查接收数据的代码示例:
```cpp
void CMyDlg::OnOpenCom()
{
if (f_open_com == true) {
f_open_com = false;
GetDlgItem(IDC_OPEN_COM)->SetWindowText(打开通信端口);
CloseHandle(hComm);
KillTimer(1000); // 关闭定时器
return ;
}
SetTimer(1000, 1000, NULL); // 设置nIDEvent为1000,时间间隔为5秒
const char *ComNo;
DCB dcb;
std::string temp(COM1);
ComNo = temp.c_str();
hComm = CreateFile(ComNo , GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
if (hComm == INVALID_HANDLE_VALUE) { // 如果端口未打开
MessageBox(打开通信端口出错!, Comm Error, MB_OK);
return ;
}
GetCommState(hComm , &dcb); // 获取当前的通信状态
dcb.BaudRate = CBR_9600;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
if (!SetCommState(hComm , &dcb)) {
MessageBox(通信端口设置出错!, Set Error, MB_OK);
CloseHandle(hComm);
return;
}
GetDlgItem(IDC_OPEN_COM)->SetWindowText(关闭通信端口);
f_open_com = true;
}
void CMyDlg::OnTimer(UINT nIDEvent)
{
char inbuff[1024];
DWORD nBytesRead, dwError;
COMSTAT cs;
ClearCommError(hComm , &dwError , &cs);
if (cs.cbInQue > sizeof(inbuff)) {
PurgeComm(hComm , PURGE_RXCLEAR );
return ;
}
ReadFile(hComm , inbuff , cs.cbInQue, &nBytesRead, NULL );
inbuff[cs.cbInQue] = \0;
m_Receive.Format(%s,inbuff);
UpdateData(false);
CDialog::OnTimer(nIDEvent);
}
```
对于串口通信定时检查的循环部分,可以重写为:
```cpp
for(int i=0;;i++) {
// 循环体内的代码...
Sleep(5);
if(i > ...) { // 假设这里的条件是判断是否达到某个阈值或发生特定事件
AfxMessageBox(错误XXX);
return;
}
}
// 在循环结束后,记得停止一些机器动作
```