{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
开启了消息循环,注意流程如下:
windows给每个窗口都维护了一个消息队列(《windows程序设计》3.1.7)
GetMessage从队列中获取一条消息,注意该函数是阻塞式的!(罗云彬,《琢石成器:Windows环境下32位汇编语言程序设计(第3版)》4.2.3)
TranslateMessage 主要用于键盘消息转换,
The return value specifies the value returned by the window procedure. Although its meaning depends on the message being dispatched, the return value generally is ignored.
"
即SendMessage是阻塞式的,调用窗口过程直至其返回后自身才返回。
如果SendMessage直接调用窗口过程,那为什么上面那种情况程序会卡死呢。
MSDN在SendMessage的Remark中说:
If the specified window was created by the calling thread, the window procedure is called immediately as a subroutine. If the specified window was created by a different thread, the system switches to that thread and calls the appropriate window procedure. Messages sent between threads are processed only when the receiving thread executes message retrieval code. The sending thread is blocked until the receiving thread processes the message.
大意是:如果目标窗口是由调用SendMessage的函数创建的,则直接调用窗口过程;如果不是,比如上面那种工作线程调用SendMessage,
则系统切换至创建窗口的线程,然后调用里面的窗口过程,此时工作线程阻塞,直至调用窗口过程的线程处理完该消息。
这样就可以理解上面那种情况为什么卡死了,因为主线程已经卡住了,没法处理其他消息,所以SendMessage无法返回。
解决方法:
1.最后不要在工作线程里搞UI操作,改为发送用户消息,让主线程去处理(上次面试时面试官这么说的)这样可能实时性在某些情况会打些折扣。
2.一定要搞,则不要使用WaitForSingleObject这种“野蛮”阻塞掉调用线程的函数,改用MsgWaitForMultipleObjects
MsgWaitForMultipleObjects有一个参考可以指定监视消息的类型,一旦该类型消息进入队列,函数会立刻返回,
函数返回时检查返回值,如果是线程结束,则继续做其他事情,如果是消息进入队列,获取并转发消息,然后继续调用MsgWaitForMultipleObjects
参考:http://blog.csdn.net/silvervi/article/details/5874212