
原因其他人说了,你的消息循环被你的函数塞住了,因为消息只能一个接一个的处理,你在一个消息的响应里发送了另一个消息,这个消息只能排在队列里面,等你一开始的响应结束之后才会处理。因此就会出现你说的情况,循环结束之后才会一下子把你在消息响应里面发送的500个消息一起给处理了。而不是你预想的发送一个处理一个。
给你一个比较简单的解决方法,就是你自己接管消息循环,分发消息。如果你了解Windows SDK编程,你一定非常熟悉下面的WinMain里面的基本代码:
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
上面代码简单解释一下:
GetMessage可以获得消息,并删除获得的消息,如果队列没有消息,则程序进入休眠状态,如果取得消息且消息不是WM_QUIT,则返回TRUE,如果是WM_QUIT,则返回FALSE。微软就是这么设计好了让你在WinMain主函数中这么使用,当用户关闭程序,系统则发送WM_QUIT,GetMessage返回FALSE,while循环就结束了,然后WinMain主函数就返回了,主函数返回程序就退出了。
TanslateMessage负责翻译WM_KEYDOWN为WM_CHAR。DispatchMessage负责分发消息到对应的窗口函数(WNDPROC)。
另外,微软提供了PeekMessage可以测试消息队列是否为空,因为如果你用GetMessage,一旦消息队列为空,则函数就被阻塞在那里,这个函数一直等到有消息来才会返回。而PeekMeesage则不论是否有消息都立刻返回。如果有消息PeekMessage返回TRUE,否则返回FALSE。指定参数PM_NOREMOVE,则只取回下一个消息,但不在队列删除消息。
下面的函数示范了你如何自己接管消息循环,分发消息。有了下面的代码,不仅你的循环会和你预想的一样执行,而且,如果你的循环很长很长,也不会出现界面卡住,因为每个循环都有机会让消息的到执行,Windows所有界面功能都是通过消息来实现的。
void CComposerDlg::OnButton2()
{
// TODO: Add your control notification handler code here
int i;
MSG msg;
for(i=0;i<500;++i)
{
m_countInsert(0,"abvc\r\n");
UpdateData(FALSE);
while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) // 测试队列
{
// PeekMessage返回了TURE,说明队列不空
GetMessage(&msg, NULL, 0, 0); // 取得一个消息
TranslateMessage(&msg); // 翻译
DispatchMessage(&msg); // 分发处理
} // 当消息处理完毕之后,while循环就会结束,因为PeekMessage返回FALSE
}
};
找不到 h 头文件,说明缺少相关的文件包含语句,而无法执行,也有可能是链接时找不到库文件。所以请检查VC6 MFC有关的目录设置:“工具”——“选项”——“目录”,在该对话框中检查:
1、include files 目录是否存在:
X:\Program Files\Microsoft Visual Studio\VC98\MFC\INCLUDE
2、Library files 目录是否存在:
X:\Program Files\Microsoft Visual Studio\VC98\MFC\LIB
如果没有,将其加上即可(其中X代表您VC6安装的盘符)。
如经以上步骤还不行,那么就考虑重装VC6,或者升级采用VC2005、2008、2010、2012、2013等版本。
希望对您有所帮助!
给你个思路吧
方法一:用SetUnhandledExceptionFilter设置一个异常处理,捕捉到异常时重新启动自己,然后在你的异常处理函数里返回EXCEPTION_EXECUTE_HANDLER让原来的程序嫁出
方法二:用监控的方式实现,例如你的主程序是mainexe,那么写一个监控程序watchexe,watch里WaitForSingleObject等待main进程退出,退出后检查它的退出码,例如你的mainexe正常退出时,退出码是0,那么在非0的时候把它重新拉起;要注意的是,这个办法如果你没处理好可能容易误判
循环m_service和m_queue的时候,循环超界了。
int server::FindNextOne(int type)
{
int ret;
int length=m_serviceGetCount();
int comtype;
POSITION pos = m_serviceGetHeadPosition();
POSITION tpos = m_queueGetHeadPosition();
while(pos!=NULL && tpos!=NULL) //同步循环m_service和m_queue
{
comtype =m_serviceGetAt(pos);
if (comtype==type) { //如果m_service当前值与type相同
ret = m_queueGetAt(tpos); //返回m_queue同一位置的值
m_serviceRemoveAt(pos); //删除当前位置并返回
m_queueRemoveAt(tpos);
return ret;
}
m_serviceGetNext(pos); //同时向后移动一个位置
m_queueGetNext(tpos);
}
return -1; //返回错误
}
1 EnableWindow()
启用和禁用控件或者窗口(设置个控件或窗口可用或不可用)可以调用CWnd::EnableWindow()函数。
BOOL EnableWindow(BOOL bEnable = TRUE);
判断控件是否可用可以调用 CWnd::IsWindowEnable函数
BOOL IsWindowEnable();
禁用控件或者窗口(设置个控件或窗口不可用)
1CWnd pWnd = GetDlgItem(IDC_EDIT1);
pWnd->EnableWindow(FALSE);
2GetDlgItem(IDC_EDIT1)->EnableWindow(false);//变灰,不可用,可见
启用控件
1CWnd pWnd = GetDlgItem(IDC_EDIT1);
pWnd->EnableWindow(TRUE);
2GetDlgItem(IDC_EDIT1)->EnableWindow(true);//还原正常,可用,可见
2ShowWindow()
设置控件或者窗口显示或不显示(可见或不可见)
GetDlgItem(IDC_EDIT1)->ShowWindow(SW_HIDE);//隐藏控件,不可见
GetDlgItem(IDC_EDIT1)->ShowWindow(SW_SHOW);//显示控件,可见
以上就是关于MFC中异常的循环全部的内容,包括:MFC中异常的循环、VC++6.0不能执行MFC程序点开resourced出错误提示:致命错误RC1015:无法打开包含文件'afxres.h'.怎么处理、mfc对话框程序崩溃后,怎么实现再次自启动等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)