我正在编写一个自定义的Wpf控件,我需要尽早获取对包含窗口的HwndSource的引用。如果可能的话,这将是1)在我的控制的构造函数中;或2)在控件添加到显示层次结构时。
如何检测HwndSource何时/是否可用?我计划使用以下代码获取引用:
var source = HwndSource.FromVisual(this) as HwndSource;
答案 0 :(得分:4)
您可以使用PresentationSource的AddSourceChangedHandler方法监听PS何时更改(HwndSource是派生PS)。
答案 1 :(得分:3)
据我所知,WPF控件不是windows。只有wpf应用程序中的窗口才有hwnd。
来自msdn网站:
“屏幕上的所有WPF元素最终都由HWND支持。当您创建WPF窗口时,WPF创建顶级HWND,并使用HwndSource将Window及其WPF内容放入HWND中应用程序中其余的WPF内容共享单个HWND。例外是菜单,组合框下拉菜单和其他弹出窗口。这些元素创建自己的顶级窗口,这就是为什么WPF菜单可能会去的原因超过包含它的窗口HWND的边缘。当你使用HwndHost在HWF中放置HWND时,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();
in vb
Dim wih As New WindowInteropHelper(myDialog)
wih.Owner = ownerHwnd
myDialog.ShowDialog()
我希望这会有所帮助。
答案 2 :(得分:2)
我总是使用Window.SourceInitialized事件来确定HWND(即HwndSource)何时可以使用。在您的情况下,您可能需要为OnVisualParentChanged方法添加覆盖。在覆盖中,向上搜索关联窗口的可视树(或使用Window.GetWindow)。
如果Window具有有效的HWND,那么您可以按原样使用它。如果没有,那么您必须订阅SourceInitialized事件。您可以从处理程序中的SourceInitialized中取消挂钩,以确保只调用一次。