3

我正在编写一个自定义 Wpf 控件,我需要尽早获取对包含窗口的 HwndSource 的引用。如果可能,这将是 1) 在我的控件的构造函数中或 2) 在将控件添加到显示层次结构时。

如何检测 HwndSource 何时/是否可用?我计划使用如下代码获取参考:

var source = HwndSource.FromVisual(this) as HwndSource;
4

3 回答 3

4

您可以使用 PresentationSource 的 AddSourceChangedHandler 方法来监听 PS 何时发生变化(HwndSource 是派生的 PS)。

http://msdn.microsoft.com/en-us/library/system.windows.presentationsource.addsourcechangedhandler.aspx

于 2011-06-10T04:02:57.317 回答
3

据我了解,WPF 控件不是窗口。只有 wpf 应用程序中的窗口具有 hwnd。

从 msdn 站点:

“屏幕上的所有 WPF 元素最终都由 HWND 支持。当您创建 WPF Window 时,WPF 会创建一个顶级 HWND,并使用 HwndSource 将 Window 及其 WPF 内容放入 HWND。您的 WPF 的其余部分应用程序中的内容共享单个 HWND。一个例外是菜单、组合框下拉菜单和其他弹出窗口。这些元素创建自己的顶级窗口,这就是 WPF 菜单可能超出窗口边缘的原因包含它的 HWND。当您使用 HwndHost 将 HWND 放入 WPF 中时,WPF 会通知 Win32 如何相对于 WPF 窗口 HWND 定位新的子 HWND。

有关 Win32 互操作性,请参阅以下链接:

http://msdn.microsoft.com/en-us/library/ms742522.aspx

编辑:为了增强解决以下评论的答案:

为了获得拥有 hwnd 的窗口句柄,您可以使用 WindowInteropHelper 类。

这个例子也是从 MSDN 文档中提取的

在c#中

WindowInteropHelper wih = new WindowInteropHelper(myDialog);
wih.Owner = ownerHwnd;
myDialog.ShowDialog();

在VB中

Dim wih As New WindowInteropHelper(myDialog)
wih.Owner = ownerHwnd
myDialog.ShowDialog()

我希望这有帮助。

于 2011-06-09T00:07:43.053 回答
2

我一直使用Window.SourceInitialized事件来确定 HWND(即 HwndSource)何时可以使用。在您的情况下,您可能需要为OnVisualParentChanged方法添加覆盖。在您的覆盖中,在可视化树中搜索关联的 Window(或使用Window.GetWindow)。

如果 Window 具有有效的 HWND,那么您可以按原样使用它。如果没有,那么您必须订阅 SourceInitialized 事件。您可以从处理程序中的 SourceInitialized 中取消挂钩,以确保它只被调用一次。

如果您的控件托管在Popup中,这将不起作用。在这种情况下,您必须获得对相关弹出窗口的引用并注意Opened事件。

于 2011-06-09T00:19:54.553 回答