【问题标题】:How to get window opened/closed/minimized messages from a native app?如何从本机应用程序获取窗口打开/关闭/最小化消息?
【发布时间】:2010-03-31 19:05:45
【问题描述】:

为这个写一个好标题很难。

我正在开发一个 WPF 应用程序,它需要了解系统上是否存在所有其他打开的窗口。我可以通过调用本机 EnumWindows 方法来做到这一点,我可以调用其他本机方法来过滤掉我感兴趣的窗口。这很好。

我遇到的问题是我想知道窗口何时打开或关闭(理想情况下是最小化)。我可以通过使用 EnumWindows 轮询来做到这一点,但我发现这非常慢,即使我将它推到另一个线程。

有没有更好的方法来获取窗口打开/关闭/最小化的通知?请记住,我对非托管代码的了解非常有限。

【问题讨论】:

  • 不可能?从这里开始:support.microsoft.com/kb/318804 除了 WH_KEYBOARD_LL 低级挂钩和 WH_MOUSE_LL 低级挂钩,您无法在 Microsoft .NET Framework 中实现全局挂钩。要安装全局挂钩,挂钩必须具有本机 DLL 导出,以便将自身注入另一个需要有效、一致的函数才能调用的进程。此行为需要 DLL 导出。 .NET Framework 不支持 DLL 导出。托管代码没有函数指针一致值的概念,因为这些函数指针是动态构建的代理。
  • 这里有一些进展:pastebin.com/1q3qj5iY 如果传递当前线程 ID,当应用程序窗口聚焦和模糊时,我确实会收到消息,但我需要来自 所有 窗口的消息。为线程 id 传递 0 以获取所有消息会导致 SetWindowsHookEx 返回 null。

标签: .net windows winapi pinvoke


【解决方案1】:

你可以使用 windows 钩子来处理这类事情。

基本上一旦设置好你的钩子,只要你感兴趣的消息被调用,你的回调就会被调用。

codeproject 上有一个很好的示例,用于使用 C# 代码设置全局系统范围的挂钩。
注意:这个项目有一个非托管的 c++ 组件,但您不需要直接使用它。

【讨论】:

  • 谢谢,我会深入研究的。我至少可以让样本运行起来。看起来它只支持开箱即用的鼠标/键盘事件,目前还不清楚我是否可以扩展它来获取我需要的消息。会看得更远...
  • 看起来这是不行的。库中只实现了鼠标和键盘挂钩,扩展它需要深入研究 C++。即使我有足够的勇气这样做,我也无法让项目从源代码运行。关于托管调用 SetUserHookCallback 的某些内容与本机签名不匹配,但我什至找不到有关该方法的任何文档。
  • @Josh Santangelo:是的,运行演示不需要您进入 C++,但要执行您想做的事情,您必须这样做。您将使用该项目作为起点。这不是微不足道的,而是非常可行的。
  • 我跳过了那个演示,但取得了一些进展。不过还是不能做全局钩子:pastebin.com/1q3qj5iY
【解决方案2】:

【讨论】:

  • 我正在使用它来获取应用程序启动时的所有窗口,但是在运行时使用它来捕获窗口列表中的更改太慢了。
  • WM_WINDOWPOSCHANGING 消息怎么样?
  • 我能够从当前进程获取窗口消息,但不能从整个操作系统获取。此处示例:pastebin.com/1q3qj5iY
猜你喜欢
  • 1970-01-01
  • 2016-07-30
  • 1970-01-01
  • 1970-01-01
  • 2012-07-20
  • 2017-08-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-07
相关资源
最近更新 更多