【问题标题】:Keep Control.Handle保持控制。处理
【发布时间】:2012-08-08 21:39:39
【问题描述】:

我有一个正在与之通信的非托管 DLL。有一个函数需要一个窗口句柄来绘制。但是,在一些 MDI 操作、表单隐藏和显示之后,句柄会发生变化。不幸的是,我无法为 DLL 提供新句柄,然后引发 System.AccessViolationException。我可以使用一些方法来防止句柄重新创建吗?

【问题讨论】:

    标签: c# .net winforms winforms-interop


    【解决方案1】:

    我有一个正在与之通信的非托管 DLL。有一个函数需要一个窗口句柄来绘制。但是,在一些 MDI 操作、表单隐藏和显示之后,句柄会发生变化。不幸的是,我不能给 DLL 一个新的句柄,然后System.AccessViolationException 就会出现。

    适当的解决方案是处理HandleCreated event 并通知DLL 句柄已更改。但是你说你不能给DLL一个新的句柄。 (为什么不呢?)

    我可以使用一些方法来防止句柄重新创建吗?

    不,没有这样的方法。

    问题是设置表单的某些属性会导致框架在内部重新创建底层窗口,这当然会导致您的表单与不同的句柄相关联。但这不是错误,它解决了某些窗口样式属性在创建时被缓存的事实,并且无法在不重新创建窗口的情况下强制更新它们。

    因此,如果您想确保窗口句柄永远不会改变,您必须确保永远不会更改导致框架重新创建其句柄的任何表单属性。

    有了ILSpy 之类的东西,您可以准确地找出这些属性/方法。罪魁祸首通常会调用一个名为RecreateHandle 的方法(在某些情况下您甚至可以调用自己来达到类似的效果)。

    我想不出另一种解决方法。无法告诉 Windows 使用与旧对象相同的句柄重新创建对象。

    【讨论】:

    • 感谢您的回答。我没有创建这个 DLL,作者也没有导出函数来改变绘图窗口。幸运的是,我找到了解决方案。当我在 MDI 容器中隐藏父窗体时,将重新创建句柄。因此,我将其从父级中删除并在再次显示表单后添加。手柄保持不变。 ☺
    猜你喜欢
    • 2012-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多