MoveWindow僵局?

时间:2009-04-20 23:39:58

标签: c++ winapi deadlock

我在线程A上有一个窗口,它在某个时刻(由于在其wndproc上接收到消息)触发了对线程B的操作,然后等待操作完成(使用某种同步机制) )。线程B然后调用MoveWindow(),在线程A的窗口(例如标准文本框)中移动子窗口。此时程序由于某种原因进入死锁状态。如果从线程A调用MoveWindow(),一切正常。有什么想法吗?

5 个答案:

答案 0 :(得分:2)

什么是“某种同步机制”?如果它是WaitFor(Multiple)Object(s),你可以使用[MsgWaitForMultipleObjects](http://msdn.microsoft.com/en-us/library/ms684242(VS.85).aspx)Ex)代替在你收到消息时醒来并按照Lucero的建议发送它。

答案 1 :(得分:2)

您可以将SetWindowPos与标志SWP_ASYNCWINDOWPOS一起使用,而不是使用MoveWindow。

原因可能是ThreadA等待ThreadB处理某个事件,但同时ThreadB等待ThreadA(拥有该窗口的线程)返回MoveWindow的结果。

答案 2 :(得分:2)

我认为@ 1800的解释是最接近的。

当您从不拥有该窗口的线程移动窗口时,我认为Windows不使用SendMessage将WM_WINDOWPOSCHANGING之类的内容传递给移动窗口的窗口过程。相反,为了确保只在正确的线程上调用窗口过程,它会发布WM_WINDOWPOSCHANGING消息并阻塞它,直到它被正确线程中运行的事件循环选中。但是,该事件循环未运行 - 它被阻止,等待MoveWindow完成。

来自@totaland和@Logan Capaldo的解决方案将起作用。

可能你不需要等到你的窗户移动了。或者,如果您确实需要确定,请使用MsgWaitForMultipleObjectsEx并运行一个小事件循环来处理发布的消息。

答案 3 :(得分:1)

您需要确保在等待时线程的消息泵正在运行。

您可能希望循环使用PeekMessage()(或GetMessage()}和DispatchMessage()

答案 4 :(得分:1)

Thread affinity of user interface objects, part 1: Window handles

  

不同的对象有所不同   线程关联规则,但   基本原则来自16位   视窗。

     

最重要的用户界面   元素当然是窗口。   Window对象具有线程亲和性。   创建窗口的线程是   窗户有一个   不可分割的关系。通俗地说,   一个人说线程“拥有”了   窗口。消息被分派到   窗口过程仅在线程上   拥有它,一般来说,   应该对窗口进行修改   仅来自拥有的主题   它。窗口管理器虽然   允许任何线程访问此类   作为窗口属性,样式,   和其他属性,如   窗口过程,以及此类访问   从窗口是线程安全的   经理的观点,   load-modify-write序列应该   通常仅限于所有者   线程。