为什么SendMessage的设计在窗口过程中的行为与在工作线程中的行为不同?

Krz*_*cha 0 windows winapi

起初我会请你不要误解这个问题.我不是在问SendMessage是如何工作的,但为什么它的工作方式与它一样.基本上,我想知道为什么不能直接从工作线程调用窗口过程,就像从窗口线程那样,而不是将消息泵入消息队列?

在工作线程的一个非常简单的例子中,我可以这样做:

WndProc(hWnd,MY_MESSAGE,wParam,lParam);
Run Code Online (Sandbox Code Playgroud)

代替:

SendMessage(hWnd,MY_MESSAGE,wParam,lParam);
Run Code Online (Sandbox Code Playgroud)

并立即得到答复.你直接打电话给WndProc有什么缺点吗?

我可以理解,当你想要将消息发送到另一个进程所拥有的窗口时,事情会变得更复杂,但是不能存在类似于SendMessage的函数,它在工作线程中的工作方式与窗口相同线?有什么理由背后没有任何存在吗?提前感谢您的任何解释.

Ste*_*eve 6

窗口过程的编写者期望所有调用都在一个线程上进行.通过使用SendMessage,可以将消息放在(线程安全的)队列上.单个线程可以将消息从队列中取出并将它们传递给窗口过程.

缺点是WndProc从另一个线程调用会引入竞争条件.某些UI对象具有线程关联.如果不遵守(例如通过WndProc从另一个线程调用),那么这可能会导致问题.设备上下文就是一个例子.根据Raymond Chen的说法

Window对象具有线程亲和性.创建窗口的线程是窗口具有不可分离关系的窗口.非正式地,有人说线程"拥有"窗口.消息仅在拥有它的线程上被分派到窗口过程,并且一般来说,应该仅从拥有它的线程对窗口进行修改.虽然窗口管理器允许任何线程访问诸如窗口属性,样式和其他属性(如窗口过程)之类的东西,并且从窗口管理器的角度看这些访问是线程安全的,但是加载 - 修改 - 写入序列通常应该受到限制到所有者线程.否则你会遇到竞争条件......