UI和主线程的关系?

时间:2021-10-26 18:27:17
    在程序的主界面上打开一个模态对话框窗口做一些操作。同时,另一个工作线程通过PostMessage向主窗口发送消息,主窗口收到消息后,把字符串显示到一个ListBox中。
    按我的理解,如果UI是主线程的一部分,当我打开一个模态对话框做一些操作的时候,这时候主线程应该是阻塞在这个对话框上的,工作线程发来的消息,主窗口是无法处理的。但实际情况是,当我在对话框上做一些操作的时候,主窗口也在很顺畅的处理来自工作线程的消息,并把字符串显示到了ListBox中。

    或者UI并不是主线程的一部分?
    对于UI和主线程或者其他工作线程的关系已经困惑了我很久了,请高人解惑。

14 个解决方案

#1


模态对话框内部有消息循环,会处理发给本线程的所有消息。

#2


晕,模态对话框阻塞的是父窗口的输入消息,比如说键盘、鼠标消息,并不影响主线程的其他消息的响应。
不然绘图消息也被阻塞,父窗口还不得白屏啊。

#3


更详细的信息可以参考MFC的模态对话框的源码。

#4


线程和消息是两码事,有UI的线程只是在线程里有个消息处理的功能。你那主线程就是个UI线程,打开模态对话框并没有阻塞主线程。想想就知道,如果要是主线程真阻塞了,那你点什么都不会有反应了

#5


学习一下

#6


这样讲每一个进程都有一个主线程,有些动作可能会阻碍主线程的工作,就另辟线程来做了,总体把握这一点来理解了。

#7


引用 1 楼 cnzdgs 的回复:
模态对话框内部有消息循环,会处理发给本线程的所有消息。


模态对话框内部的消息循环虽然会处理发给本线程的所有消息,但由于主线程阻塞在了调用这个模态对话框的某个函数的某行,应该说,主界面是不会被刷新的。

我让一个工作线程建立消息循环,其他线程向它发送消息,它收到一条消息开始执行一个函数时,对下一条消息就不会做出反应,直到之前的函数执行完,才会处理其他消息。

但带有UI的主线程好像不是这样的,感觉UI好像和主线程是两个并行的线程一样。在模态对话框上进行操作的时候,主界面窗口依然可以刷新。

#8


本来就是并行(看你怎么理解这个概念了),模态对话框阻塞主窗口的输入输出,但是不影响父窗口消息。
刷新靠的是WM_PAINT消息,明白了吧?

#9


CDialog::DoModal函数内部实现了一个私有的消息循环,建议你看看它的源代码

#10


消息是可以重入的,也就是说消息响应函数会被间接地嵌套调用,一个函数在返回之前可以重新进入此函数。例如:
1、收到消息WM_TEST,窗口过程调用OnTest
2、OnTest中启动模式对话框
3、模式对话框启动内部消息循环接收消息
4、内部消息循环再次收到一个WM_TEST消息,窗口过程被调用
5、窗口过程中调用OnTest,这个调用就是OnTest的间接嵌套,也就是函数重入,此时第一次的OnTest并没有返回,但线程没有被阻塞。

#11


收藏

#12


看看MFC模式对话框

#13


收藏,理解,但是还没理解透,看源码去了

#14


谢谢大家的回复。
过了一段时间来看这个,感觉明白了不少。
对MFC这套体系看来还是理解的太有限,需要看看MFC的代码了。

#1


模态对话框内部有消息循环,会处理发给本线程的所有消息。

#2


晕,模态对话框阻塞的是父窗口的输入消息,比如说键盘、鼠标消息,并不影响主线程的其他消息的响应。
不然绘图消息也被阻塞,父窗口还不得白屏啊。

#3


更详细的信息可以参考MFC的模态对话框的源码。

#4


线程和消息是两码事,有UI的线程只是在线程里有个消息处理的功能。你那主线程就是个UI线程,打开模态对话框并没有阻塞主线程。想想就知道,如果要是主线程真阻塞了,那你点什么都不会有反应了

#5


学习一下

#6


这样讲每一个进程都有一个主线程,有些动作可能会阻碍主线程的工作,就另辟线程来做了,总体把握这一点来理解了。

#7


引用 1 楼 cnzdgs 的回复:
模态对话框内部有消息循环,会处理发给本线程的所有消息。


模态对话框内部的消息循环虽然会处理发给本线程的所有消息,但由于主线程阻塞在了调用这个模态对话框的某个函数的某行,应该说,主界面是不会被刷新的。

我让一个工作线程建立消息循环,其他线程向它发送消息,它收到一条消息开始执行一个函数时,对下一条消息就不会做出反应,直到之前的函数执行完,才会处理其他消息。

但带有UI的主线程好像不是这样的,感觉UI好像和主线程是两个并行的线程一样。在模态对话框上进行操作的时候,主界面窗口依然可以刷新。

#8


本来就是并行(看你怎么理解这个概念了),模态对话框阻塞主窗口的输入输出,但是不影响父窗口消息。
刷新靠的是WM_PAINT消息,明白了吧?

#9


CDialog::DoModal函数内部实现了一个私有的消息循环,建议你看看它的源代码

#10


消息是可以重入的,也就是说消息响应函数会被间接地嵌套调用,一个函数在返回之前可以重新进入此函数。例如:
1、收到消息WM_TEST,窗口过程调用OnTest
2、OnTest中启动模式对话框
3、模式对话框启动内部消息循环接收消息
4、内部消息循环再次收到一个WM_TEST消息,窗口过程被调用
5、窗口过程中调用OnTest,这个调用就是OnTest的间接嵌套,也就是函数重入,此时第一次的OnTest并没有返回,但线程没有被阻塞。

#11


收藏

#12


看看MFC模式对话框

#13


收藏,理解,但是还没理解透,看源码去了

#14


谢谢大家的回复。
过了一段时间来看这个,感觉明白了不少。
对MFC这套体系看来还是理解的太有限,需要看看MFC的代码了。