最近在写代码时,
因为GetDlgItem(IDC_XXXX)->SetWindowText由于RELEASE版本而出现了一些问题。
查看MSDN的说明,里面说到象SetWindowText、GetWindowText等函数实际上是给相应窗口或控件窗口发送了消息。
突然想到GetDlgItem(IDC_XXXX)->SetWindowText或者SetDlgItemText等操作在程序中出现的次数非常多,而且出现在我本身的消息响应过程中,如OnButon()中。
比如在OnButon()中我执行了SetDlgItemText(),我能马上在界面上看到改变的结果,
而此时OnButton()尚未执行完毕,例如我在退出OnButon()前放置一个AfxMessageBox.我想:
消息在线程的消息队列中是被序列化的,
由SetDlgItemText发送的消息(SendMessage还是阻塞的)此时应该还在消息队列中。
我的OnButton还未返回,GetMessage根本还未执行,系统怎么会先响应SetDlgItemText发送的消息呢
即使该消息一般是由DefWindowProc来处理。而且这里也不存在一个多线程的问题,
我原想或许控件由系统自动新开了线程来处理窗口下控件的消息,似乎也不是。
我使用2000的性能监视器查看程序的线程数目始终为1。
那作为单线程的程序,我的OnButton还在执行,不存在所谓线程抢先的问题。而且即使SendMessage比PostMessage、WM_QUIT、键盘鼠标输入等其它消息有优先权,但我的消息循环还根本没有GetMessage,DispatchMessage都还没有返回呢,怎么回事呢,平时觉得理所应当的事情,细一想,就想不通了。哪位仁兄帮忙解释一下吧,谢谢了!

解决方案 »

  1.   

    补充一点:
    控件应该有自己的窗口处理过程,
    但按理说,应该也是由拥有该控件的线程的消息循环来发送消息给它的,
    但消息循环还没有返回到GetMessage,而正在处理OnButton()过程。
    难道真是系统开了新的线程了?谢谢!
      

  2.   

    原则上来说,所有的消息都是要先入message queue排队,但windows系统在设计时就考虑到某些消息是不宜入队后再做处理的,例如你看到的SetWindowText(),它是由window系统直接调用你的wndproc实现的,而不是先将WM_SETTEXT入队,等你GetMessage()后才经过DispatchMessage(),再调用wndproc的.你的关于这是一个单线程的概念是对的,但当加入wndproc这个回调函数之后,你的程序与系统之间的关系就不再像一根线那么直接了当了.
      

  3.   

    关键原因是AfxMessageBox,具体原理我不是很清楚,但猜想是在模态对话框的API函数中包含了消息循环的代码(也就是Getmessage() dispatchmessage()之类),而消息循环是属于线程的(而不是窗口!),因此处在同线程主窗口的消息也得到了响应。
    这点其实不需要SetText()函数就可以验证,你在Onbutton里直接写个AfxMessageBox,对话框弹出后Onbutton实际是被阻塞的,而此时你拖动对话框,主窗口仍然能够正确地重绘,说明主窗口的WM_PAINT消息仍然是正确地被处理的。
    再做另一个试验,说明写在别处的消息循环代码仍有效。你在Onbutton里写一个死循环,则界面会死掉,而在死循环里加入消息循环代码,即Getmessage() dispatchmessage()之类,界面仍的得到正确的更新。
      

  4.   

    关于这一点请见MSDN的Message Routing说明,消息有两种,一种是入队列的,但还有一种直接进入处理过程的消息,因此不会堵塞。