在一个按钮的响应函数里,比如OnBnClickedXXX(),如果写上一句Sleep(10000),那么点击这个按钮后,整个程序会卡住10秒。这很好理解,因为那条按钮的WM_COMMAND消息一直没处理完,所以消息队列里的其它消息处于阻塞状态。但是假如我写的不是Sleep(),而是XXX.DoModal(),见证奇迹的时刻就来了,明明这条WM_COMMAND消息没处理完——DoModal()后面的代码还没执行,为什么这个时候主窗口和DoModal出来的窗口都能继续处理消息?——比如WM_PAINT、WM_SETCURSOR等等。。为什么呢?
spy一下就知道了,主窗口还能继续处理WM_PAINT消息的;或者我们能看到主窗口能不断重绘,也就证明它在成功地处理WM_PAINT。另外,你还可以SetTimer一下,就知道主窗口还能处理消息了。
domodle里还是比较复杂的,在domodle()里是将父窗口进行了disable,和控件是一样的,disable,绘制消息还是会响应的,并不是完全的品比所有消息。
我们来看看经典的消息循环—— // 主消息循环:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}msg的结构体有一个HWND成员,也就是说,一个程序所有的窗口的消息都是这一个循环在处理,何来另一个线程?如果有,那个线程什么时候开启,又是怎么样工作的呢?其实纯Win32工程里,比如helloworld工程,也有一个帮助对话框,一样是模态的,也一样有这样的问题,可见这个现象不是MFC才有的。
屏蔽消息可以理解,比如,主窗口已经没收到WM_LBUTTONDOWN了。但问题是,在DoModal()的地方,这个WM_COMMAND消息还没处理完,消息循环是怎样继续的呢?为什么还可以有WM_PAINT这样的消息继续循环?
看这个吧http://wenku.baidu.com/view/1f9e5c669b6648d7c1c74655.html
否则一个直观的问题就是当窗口被遮挡再重现父窗口无法重绘啊
我认为是阻塞全部的,那些重绘消息我看是模态对话框内部以某种方式让父窗口得以调用响应重绘消息的函数。你可以做个实验,在Win32的helloworld工程,弹出帮助对话框后,把断点设在主消息循环里。除非帮助对话框被关闭,否则该断点一直不会命中。