我正在调试一个应用程序,它主要是在非托管代码之上的Winforms UI。一些UI代码不是WinForms:它使用DirectX直接绘制到某些Panel组件的表面上。为了做到这一点,组件的窗口句柄在创建后被记录,并且任何需要执行此DirectX显示的模块所需的句柄的后续调用(例如GetWindowRect())使用此句柄。这种机制已经存在了一段时间,没有看到我将要描述的问题,尽管我们可能只是幸运。使用它的程序员不再适用于我。
我试图解决的问题是,非常间歇性地,此区域的显示被破坏。从后台线程调用此例程。我在我的应用程序日志中看到,例如,对GetWindowRect()的调用将突然,并伴随绘图问题,返回垃圾坐标。 Window句柄本身没有损坏,我有理由相信我们没有覆盖Windows数据结构;我可以停止并重新启动我们的显示流,GetWindowsRect()将使用相同的Windows句柄再次开始返回良好的坐标。
如果这是在.NET级别,我会使用Invoke将绘制推迟到主线程。我的问题是,我们是否应该为此DirectX呼叫做同样的事情?我试图找到微软关于不在后台线程中绘图的警告,提醒自己是否扩展到使用Windows句柄;谁能指点我这个?
PC
答案 0 :(得分:0)
Window handles have thread affinity
最重要的用户界面 元素当然是窗口。 Window对象具有线程亲和性。 创建窗口的线程是 窗户有一个 不可分割的关系。通俗地说, 一个人说线程“拥有”了 窗口。消息被分派到 窗口过程仅在线程上 拥有它,一般来说, 应该对窗口进行修改 仅来自拥有的主题 它。窗口管理器虽然 允许任何线程访问此类 作为窗口属性,样式, 和其他属性,如 窗口过程,以及此类访问 从窗口是线程安全的 经理的观点, load-modify-write序列应该 通常仅限于所有者 线程。