1

我正在尝试“挂钩”到窗口的消息以检测最小化/最大化。我环顾四周,认为这样做的唯一/最佳解决方案是挂钩窗口的消息,并检查 WM_WINDOWPOSCHANGED 消息,然后检查它的状态。

我遇到了一个问题。

System.Windows.Interop.HwndSource source = System.Windows.Interop.HwndSource.FromHwnd(System.Diagnostics.Process.GetProcessesByName("notepad")[0].MainWindowHandle);
System.Windows.Interop.HwndSourceHook hook = new System.Windows.Interop.HwndSourceHook(WndProc);
source.AddHook(hook);

它会给我一个“未设置对象实例的对象引用”。“source.AddHook ...”上的错误。设置断点时,源变量为空也很明显。换句话说:它无法在第一行获取 HwndSource。

我知道使用“WindowInteropHelper”是可能的,但那是当您将实际窗口作为 Windows.Window 可用时,但在我的情况下我没有。

任何变通方法/解决方案将不胜感激,
René Sackers

PS我100%确定在执行代码时记事本正在运行,并且它设法找到它,它是主窗口句柄。

4

2 回答 2

10

HwndSourceHwndSourceHook不要做你想做的事。它们仅存在于 WPF 和标准 Win32 窗口之间的互操作 - 在同一进程中。它们不能用于在不同进程中挂钩窗口的窗口过程。

HwndSource.FromHwnd() 不会创建新的 HwndSource 对象,它“返回指定窗口的 HwndSource 对象”。如果 hWnd 没有与之关联的一个,FromHwnd()将返回 null。这就像System.Windows.Forms.Control.FromHandle从记事本调用 hWnd - 由于记事本窗口不是 WinForms 控件,因此也会返回 null。

挂钩另一个进程的窗口过程的方法是使用SetWindowsHookEx。为了挂钩另一个进程,代码必须用 C 或 C++ 编写

于 2011-10-22T14:25:58.613 回答
1

你在滥用WindowInteropHelper. 构造函数的文档指出:

为指定的 Windows Presentation Foundation (WPF) 窗口初始化 WindowInteropHelper 类的新实例。

记事本窗口不是 WPF 窗口,这就是为什么FromHwnd返回null.

事实上,我不相信它可以在一个单独的进程中为一个窗口工作,即使另一个窗口是一个 WPF 窗口。

于 2011-10-22T14:29:57.280 回答