【发布时间】:2012-08-08 21:39:39
【问题描述】:
我有一个正在与之通信的非托管 DLL。有一个函数需要一个窗口句柄来绘制。但是,在一些 MDI 操作、表单隐藏和显示之后,句柄会发生变化。不幸的是,我无法为 DLL 提供新句柄,然后引发 System.AccessViolationException。我可以使用一些方法来防止句柄重新创建吗?
【问题讨论】:
标签: c# .net winforms winforms-interop
我有一个正在与之通信的非托管 DLL。有一个函数需要一个窗口句柄来绘制。但是,在一些 MDI 操作、表单隐藏和显示之后,句柄会发生变化。不幸的是,我无法为 DLL 提供新句柄,然后引发 System.AccessViolationException。我可以使用一些方法来防止句柄重新创建吗?
【问题讨论】:
标签: c# .net winforms winforms-interop
我有一个正在与之通信的非托管 DLL。有一个函数需要一个窗口句柄来绘制。但是,在一些 MDI 操作、表单隐藏和显示之后,句柄会发生变化。不幸的是,我不能给 DLL 一个新的句柄,然后
System.AccessViolationException就会出现。
适当的解决方案是处理HandleCreated event 并通知DLL 句柄已更改。但是你说你不能给DLL一个新的句柄。 (为什么不呢?)
我可以使用一些方法来防止句柄重新创建吗?
不,没有这样的方法。
问题是设置表单的某些属性会导致框架在内部重新创建底层窗口,这当然会导致您的表单与不同的句柄相关联。但这不是错误,它解决了某些窗口样式属性在创建时被缓存的事实,并且无法在不重新创建窗口的情况下强制更新它们。
因此,如果您想确保窗口句柄永远不会改变,您必须确保永远不会更改导致框架重新创建其句柄的任何表单属性。
有了ILSpy 之类的东西,您可以准确地找出这些属性/方法。罪魁祸首通常会调用一个名为RecreateHandle 的方法(在某些情况下您甚至可以调用自己来达到类似的效果)。
我想不出另一种解决方法。无法告诉 Windows 使用与旧对象相同的句柄重新创建对象。
【讨论】: