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