WPF - 是否必须处置 HwndSource?

2024-05-26

我在用着HwndSource在非主窗口的 WPF 窗口中,为了挂钩窗口过程 (WndProc) 来接收一些消息:

WinSource = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
WinSource.AddHook(new HwndSourceHook(WndProc));

HwndSource实施IDisposable。 MSDN 不清楚我何时/应该处置它。的文档HwndSource.FromHwnd https://msdn.microsoft.com/en-us/library/system.windows.interop.hwndsource.fromhwnd%28v=vs.110%29.aspx解释上面的技术:

您可以使用此方法为不是显式互操作窗口的窗口返回 HwndSource。其程序是:

  1. 创建一个 WindowInteropHelper 实例(提供主 Window 作为构造函数参数)。
  2. 从该 WindowInteropHelper 实例获取 Handle 属性的值。
  3. 将该 HWND 值作为参数传递给 FromHwnd。

进而:

如果您随后想要向窗口添加常规 AddHook 消息处理,则此技术会很有用。然而,每当您创建 HwndSource 时,您也有责任销毁它。即使应用程序 HwndSource 的 Application 对象已释放,情况也是如此。

(重点是我的)

然而,在硬件源 https://msdn.microsoft.com/en-us/library/system.windows.interop.hwndsource%28v=vs.110%29.aspx类文档,我们看到:

对象生命周期

HwndSource 是常规公共语言运行时 (CLR) 对象,其生命周期由垃圾收集器管理。由于 HwndSource 代表非托管资源,因此 HwndSource 实现 IDisposable。 [...] 对于某些互操作场景,可能需要从互操作代码中显式调用 Dispose。

关于钩子:

实际的钩子由弱引用保存。因此,请确保管理钩子委托的生命周期。


我无法对此给出完整的答案,但根据最近的经验,我可以说你不应该处置HwndSource对象太早 - 具体来说,直到它引用的窗口关闭为止。

我只是在调试一个这样完成的场景:

using(var source = HwndSource.FromHwnd(window.HWnd()))
{
     source.AddHook(hook);
}

其结果是,在源被处理后,窗口立即变得不起作用(不再处理消息)。

简要浏览一下参考源FromHwnd(),似乎它总是会为同一个窗口返回相同的对象。我认为这就是为什么你不能处置source只是因为你自己的代码是用它完成的。显然HwndSource.Dispose()不只是清理HWndSource对象,而是一些非托管窗口本身。

注意到这一点后,现在我也看到了 HWndSource文档 https://learn.microsoft.com/en-us/dotnet/api/system.windows.interop.hwndsource says:

同步调用Dispose立即销毁Win32窗口

这似乎是我所观察到的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WPF - 是否必须处置 HwndSource? 的相关文章

随机推荐

  • 在子网站中使用邮政和 Hangfire

    我一直在尝试在我的 MVC5 站点上使用 Postal 当我将我的网页托管为子网站时 即http localhost 子站点 http localhost Subsite我收到错误 虚拟路径 映射到另一个应用程序 这是不允许的 我已经将其调
  • 将字符串值赋给指针

    char tempMonth char month 4 month 0 j month 1 a month 2 n month 3 0 如何将月份分配给 tempMonth 谢谢 最后如何打印出来 thanks In C month mon
  • 如果该值未在语句中的其他任何地方使用,为什么要使用 ++i 而不是 i++?

    我很清楚在 C 中 int someValue i array i otherValue 相比之下有不同的效果 int someValue i array i otherValue 但每隔一段时间我就会看到 for 循环中带有前缀增量的语句
  • wglCreateContextAttribsARB 函数崩溃

    我尝试写下代码 我有InitializeOGL 的代码 bool Ogl InitializeOGL bool vSync cout lt lt Init OpenGL lt
  • 按时间范围聚合

    我有一个数据集 其中包含日期 yyyy mm dd 和时间 h m s 以及温度 float 作为单独的列 我想通过平均函数聚合每天的温度值 问题是 我不知道如何查询时间属性来表示例如聚合 h m 0 5 s and h m 5 10 s
  • 作为计划任务运行 C# 应用程序

    我有一个 C 应用程序 设计为与 Windows 窗体一起运行 但现在需要作为计划任务运行 我对此遇到了问题 我认为这是因为它需要 无头 因为它不应该有用户环境的概念 该程序已编写为无人值守运行 因为它有一个 AUTO 参数 然后该参数将从
  • FullCalendar 重复事件创建重复项

    我正在为我的新网站实现一个日历 我从后端应用程序检索事件并使用 fullcalendar 在模式中显示结果 我还使用 fullcalendar 的重复功能 https fullcalendar io docs recurring event
  • 特定代码行的类似装饰器的语法

    链接主题 但不重复 装饰器对代码的特定行而不是整个方法进行计时 https stackoverflow com questions 30433910 decorator to time specific lines of the code
  • Bootstrap 4、导航栏固定顶部和其他粘顶元素

    这里是再现 https jsbin com lawafu edit html 输出 https jsbin com lawafu edit html output 这是一个错误吗 一个失误 一个问题 一个无法实现的想法 Before scr
  • 如何用该单词的单一版本替换重复单词

    我正在尝试使用 C 处理似乎使用语音转文本的文字记录 我遇到的一个主要问题是重复单词和 或短语 我很想使用正则表达式来替换它们 这里有些例子 我我我真的很想去 但是我不去 去不了 我真的很想使用正则表达式替换 所以它会变成这样 我真的很想去
  • XGBoost 产生预测结果和概率

    我可能正在文档中查看它 但我想知道 XGBoost 是否有办法生成结果的预测和概率 就我而言 我正在尝试预测多类分类器 如果我能返回Medium 88 那就太好了 分类器 中 预测概率 88 参数 params max depth 3 ob
  • C++ 类的互斥成员导致编译错误

    我不确定为什么当我向 myClass 添加互斥体成员时会发生这种情况 在本例中为 mu Error C2661 std tuple lt void thiscall MyNameSpace myClass void MyNameSpace
  • 适用于 Web 和移动设备的 ASP.NET Web API 社交身份验证

    我的问题有点复杂 所以请耐心等待我 因为我试图很好地阐明我正在努力解决的问题 Goal 拥有一个 ASP NET 网站 允许用户通过用户名 密码或也具有 API 的社交网站 Facebook Twitter Google 等 注册和登录 该
  • 如何在Android Studio中授予对registry.bin的访问权限?

    每当我打开 Android Studio 3 0 1 时 Gradle 构建都会失败 错误如下所示 它以前工作正常 我不记得对其设置进行过任何更改 不过 现在已经不会再继续下去了 请帮忙 我被困住了 关闭 Android Studio 并尝
  • 使用 C# .NET 从操纵杆获取输入

    我在谷歌上搜索了这个 但我想到的唯一的东西已经过时并且不起作用 有人知道如何使用 C NET 获取操纵杆数据吗 由于这是我在研究 C 中的操纵杆 游戏手柄输入时在 google 上获得的最高点击次数 因此我认为我应该发布一个回复供其他人查看
  • 帧缓冲区和在 opengl 中使用着色器

    我对帧缓冲区有点困惑 我想要做的是使用附加了多个纹理的帧缓冲区 填充每个纹理 然后使用着色器组合 混合 所有纹理以创建新的输出 听起来很容易 是的 我也是这么想的 但我不明白 如何将当前绑定的纹理传递给着色器 您需要的是将纹理放入特定的槽中
  • JavaScript 中的平等[重复]

    这个问题在这里已经有答案了 在 javascript 中工作时 有人可以为我提供关于相等 不相等和类型强制测试的良好参考或解释吗 从我读到的内容中 我看到使用 eqeq 与 eqeqeq 有两个思想原则 有些人认为您不应该使用 eqeq 而
  • 使用 ACPI 在 MS-DOS 中关闭计算机

    我在基于 Pentium 的计算机上运行 MS DOS 6 22 主板支持 ACPI 并且想知道是否有一个可以用来关闭计算机的汇编语言例程 或者它是否比那个更难 即主板 具体的 基本上 我想创建一个小程序来从命令行关闭计算机 这是专门为此编
  • 从 ProcessThreadCollection 中按名称获取正在运行的线程

    在搜索了 Stack Overflow 问题并进行了一些谷歌搜索后 我仍然没有得到它 我知道您可以使用 Thread isAlive 方法检查单个线程是否正在运行 但我想检查特定的 FooThread 是否仍在当前进程的所有正在运行的线程之
  • WPF - 是否必须处置 HwndSource?

    我在用着HwndSource在非主窗口的 WPF 窗口中 为了挂钩窗口过程 WndProc 来接收一些消息 WinSource HwndSource FromHwnd new WindowInteropHelper this Handle