之前在做MFC程序的时候遇到了一个问题,非模态窗口一旦创建(Create并ShowWindow函数)之后,在exe点击运行的时候这个非模态窗口总是一闪而过,在解决完一闪而过的问题又遇见了未响应的问题。(原因在下边)
我的程序是在一个线程池中的线程函数里,有一个Recv函数在等待接收消息,如果这个消息要程序建立一个窗口,则线程调用另一个创建窗口函数(这个函数包含Create和ShowWindow函数)(线程里边调用的函数也在线程中)。
但是奇怪的是,在线程中DoMadol()弹出模态窗口,却可以正确的显示出来。但是因为程序在创建完成窗口之后还要继续向下执行其他的代码,不能用阻塞型的窗口,所以必须解决这个问题。
后来了解到原因总结如下:
(1)如果你是在线程中定义的 窗口指针 并进行 new ,随着当前线程的结束,窗口就会消失。后来我把非模态窗口类的指针的定义放在了类的成员中,可是新的Bug出来了,(哈哈,我就是专业写bug的),就是虽然不会一闪而过了,但是弹出的非模态窗口却成了未响应,给我卡死了,这个烦了我一天将近。
(2)上边未响应的原因:普通的线程没有消息机制,在这个线程创建出来的非模态窗口不能响应任何键盘鼠标的消息,应该是窗口的内部在捕获消息的时候陷入了死循环(我猜的)
(2)模态对话框有自己的一套消息机制。
解决的方法:
(1)在线程中传入主窗口的this指针,通过this->PostMessage()或者this->SendMessage()函数向主窗口发送消息,执行与自定义消息相关的函数(即自己的创建窗口的函数),利用它的消息机制使得非模态窗口可以响应消息就不会卡死未响应了,个人觉得SendMessage更好,如果你想创建完窗口并立即通过它的this指针调用该非模态窗口的函数执行和这个窗口有关的功能的话,SendMessage会立马执行你的创建窗口的函数,在里边 new一个窗口类 、Create、ShowWindow之后,该窗口的指针就有效,等回到线程中后该非模态窗口的this指针有效,然后你通过指针调用窗口类的函数。我当时开始的时候先用了PostMessage(),这个PostMessage()是非阻塞的,只是投递了消息通知执行与之关联的函数,不管函数执行完与否,都在线程中会继续下去,然而紧接着我却需要这个非模态窗口的指针调用函数,而这时指针还为NULL,还没有new,就直接中断报错了。
(2)这个方法不太推荐,我也没试过,看别人的,因为又得再开一个新线程(专门用来创建窗口并添加消息循环)(开销大)。在你的线程原来想创建非模态窗口得地方再创建一个新的线程,这个新的线程得大概内容如下:
DWORD WINAPI Thread(LPVOID Parameter)
{
//new 一个窗口类对象
//Create函数创建一个窗口
//ShowWindow展示窗口
//在这三步之后: 自己添加消息循环
MSG msg={0};
while(GetMessage(&msg,0,0,0)) //得到消息
{
TranslateMessage(&msg); //转换消息
DispatchMessage(&msg); //分发消息
}
}
真的是 三行代码就有两个Bug,调试了整整一天人都晕了。