由模态对话框引起的程序错误

ddoeddoe 2008-03-14 06:19:56

首先我定义了一个串口类创建了一个接收线程,当串口收到数据的时候发送消息到主框架(mainframe)进行数据处理,此时如果弹出一个模态对话框(例如messagebox),就有可能导致程序错误,不是每次弹出都有错误,但是多弹出几次就一定会出现一个“致命的程序错误”,如果弹出的是非模态的对话框就没有问题.
出现错误提示的同时,也会弹出下面程序里面由于不能从串口读取数据而弹出的“Error in read from serial port”对话框。


while (pThis->m_hComPort != INVALID_HANDLE_VALUE)
{

//等待串口的事件发生
WaitCommEvent (pThis->m_hComPort, &dwCommModemStatus, 0);

if (dwCommModemStatus & EV_RXCHAR)
{
ClearCommError(pThis->m_hComPort,&dwErrorFlags,&ComStat);

//cbInQue返回在串行驱动程序输入队列中的字符数
dwLength=ComStat.cbInQue;
if(dwLength>0)
{
//从串口读取数据
char* buf = new char[dwLength];
fReadState=ReadFile(pThis->m_hComPort,buf,dwLength,&dwLength,NULL);
if(!fReadState)
{
//不能从串口读取数据
MessageBox(NULL,TEXT("Error in read from serial port"),TEXT("Read Error"),MB_OK);
return;
}
else
{

//把数据赋值给全局变量
memset(pThis->m_RecvString, 0, 100);
memcpy(pThis->m_RecvString, buf, dwLength);
::PostMessage(pThis->m_ParentWnd, WM_RECV_DATA, 0, dwLength);//发送消息至主框架
}

delete[] buf;
}
}
GetCommModemStatus (pThis->m_hComPort, &dwCommModemStatus);

}

是由于模态对话框引起的线程阻塞?内存泄露? 还是什么原因.....

但是如果把::PostMessage(pThis->m_ParentWnd, WM_RECV_DATA, 0, dwLength);修改成为
SendMessage(pThis->m_ParentWnd, WM_RECV_DATA, 0, dwLength);就不存在这样的问题了...为什么呢?

相当于现在我有两个线程,一个主线程,一个是串口的接受线程,而从接收线程用PostMessage发消息会出错(在有模态对话框的情况下),模态对话框会导致这两个线程怎样?
...全文
128 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
ddoeddoe 2008-03-18
  • 打赏
  • 举报
回复
模态对话框会使得主线程不工作么?
datablader 2008-03-18
  • 打赏
  • 举报
回复
SendMessage必须等消息函数处理完成之后才能继续,所以这里的pThis-> m_RecvString永远是正确的数据。
但是,如果用PostMessage,那在消息函数处理进行的时候,pThis-> m_RecvString的内容会被memset(pThis-> m_RecvString, 0, 100);
memcpy(pThis-> m_RecvString, buf, dwLength);
这两行修改。
所以其结果是如果在消息函数里面有对pThis-> m_RecvString的操作,很有可能出现内容非法,比如字符串长度不再正确。
ddoeddoe 2008-03-17
  • 打赏
  • 举报
回复
如果是内存操作非法,也就是说用postmessage即使不弹出非模态的对话框,程序运行一段时间也会出错?
那非模态的对话框对程序又有什么影响呢?
ddoeddoe 2008-03-17
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 luhongyu2108 的回复:]
模态对话框回使主线程不接收消息
[/Quote]
这样说对么?
jameshooo 2008-03-14
  • 打赏
  • 举报
回复
当使用PostMessage时,一定要对缓冲区进行保护,否则内存数据可能会乱套。
如果在主线程消息响应函数中弹出模式对话框而没有人为关闭的话,这个对话框会不断弹出(函数被重入,相当于在进行递归调用),即使缓冲区数据没有乱套,最后也会发生堆栈溢出错误。
Eleven 2008-03-14
  • 打赏
  • 举报
回复
PostMessage()和SendMessage()的区别,SendMessage()可以立即得到返回的结果,而PostMessage()和词面上的意思一样,不能立即得到返回的结果!
mr.zhoux 2008-03-14
  • 打赏
  • 举报
回复
是操作非法内存了...
::PostMessage(pThis-> m_ParentWnd, WM_RECV_DATA, 0, dwLength);//发送消息至主框架


PostMessage是非阻塞的,消息队列在处理消息后也有可能在获得线程运行时间片的时候buf 已经delete了,所以就会崩溃..

而SendMessage是保证WM_RECV_DATA处理完毕后才继续进行下一个操作,你的内存还存在.
cnzdgs 2008-03-14
  • 打赏
  • 举报
回复
因为你的两个线程共用m_RecvString,如果是PostMessage,消息发出去后立即返回,然后继续接收数据,收到数据后又要复制到m_RecvString中,而此时m_RecvString可能正在被主线程使用,所以会出错。如果用SendMessage,消息发送出去后还要等到消息被处理完之后才会返回,这时主线程已经不使用m_RecvString了,所以不会有问题。
在这个问题中,模态对话框与非模态对话框的差别在于:模态对话框要等待一段时间(人为操作)才会返回,非模态对话框创建后立即返回,两者所需要的执行时间相差很多,所以出现问题的几率也相差较大。
luhongyu2108 2008-03-14
  • 打赏
  • 举报
回复
模态对话框回使主线程不接收消息

15,466

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧