关于自封装的消息循环函数的改进问题
各位高手, 本人利用AfxBeginThread开辟了一个UI线程,并自写了一个消息循环函数,希望以后可以封装入DLL内。
上网搜索了不少例子,但都感觉讲的不够详细,在此把自己写的贴出来,当然这个函数存在一定的缺陷,感觉有点冗繁,希望大家指正。
改进后也方便其他人学习参考。
如下代码:
BOOL CTestDlg::DoLoop()
{
MSG msg;
BOOL bRet;
while(1)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))// 从Windows消息队列中取出消息
{
bRet = GetMessage(&msg, NULL, 0, 0);
if(bRet != 0)
{
if(bRet == -1)//判断返回值是否有问题
{
AfxMessageBox(_T("Handle the error and possibly exit!"));
break;
}else{//以下分情况讨论获取到的消息对应什么操作
switch(msg.message)
{
case WM_CLOSE:
DestroyWindow();
break;
case WM_DESTROY:
delete this;
PostQuitMessage(0);
break;
default:
TranslateMessage(&msg);
DispatchMessage(&msg);
break;
}
}
}// end of inner if
if(!AfxGetApp()->PreTranslateMessage(&msg))// 如果无法预处理消息
{
::TranslateMessage(&msg);// 转换消息
::DispatchMessage(&msg); // 发送消息
}
}
AfxGetApp()->OnIdle(0);
AfxGetApp()->OnIdle(1);
}// end of while
return TRUE;
}
[解决办法]
建议不要封装消息循环代码,而是按照实际需求来写,原因大概有几点:
1、消息循环的写法有很多种,而且作用范围不一样,很难做到完全兼容。
2、在消息进入窗口过程之前,很可能需要进行某些过滤,对话框通常有IsDialogMessage调用的要求,MFC有PreTranslateMessage的要求,WTL也有PreTranslateMessage的要求,有时可能也有TranslateAccelerator的要求,有些情况是不需要TranslateMessage的(当然写了也无妨)。
3、线程消息和窗口消息不是在所有情况下都等同对待的。
4、不是所有WM_DESTROY消息都需要调用PostQuitMessage的。
5、某些消息循环还需要等待同步信号,这种情况下GetMessage的调用就是不合适的。
另,比你的代码冗繁得多的消息循环代码多的是,不用担心这个。
[解决办法]
[解决办法]
我感觉你的思维很乱,我觉得你应该找本mfc的书系统的看一下,重点搞清楚windows的消息机制,你对windows的消息机制还没搞清楚
不过我也解释不清楚你的问题
你的PreTranslateMessage函数处理鼠标左键,跟按键消息是没错
后来又,只是无法响应鼠标消息
却可以相应 键盘消息……
这个确实不知道是什么情况,这个问题应该调试能很快找到原因吧
顺便问下你工作多长时间了?
[解决办法]
从消息循环上已经看不出有什么问题,估计与窗口的创建及消息响应有关,建议你另做一个简单的测试程序来分析这个问题。
[解决办法]
你的每个子窗体的确是在新的UI线程中的,这点没错。
1.主窗体无法响应鼠标消息是因为CtestDlg重载了OnNcLButtonDown函数,代码改成:
- C/C++ code
void CTestDlg::OnNcLButtonDown(UINT nHitTest, CPoint point) { m_bDig = TRUE; CDialog::OnNcLButtonDown(nHitTest,point); //新添加的代码}