我需要访问我的一些WPF窗口的Win32窗口句柄,以便我可以处理Win32激活消息 . 我知道我可以使用 PresentationSource.FromVisual
或 WindowInteropHelper
来获取Win32窗口句柄,但是如果尚未创建WPF窗口,我遇到了问题 .
如果我使用 PresentationSource.FromVisual
并且尚未创建窗口,则返回的 PresentationSource
为空 . 如果我使用 WindowInteropHelper
并且尚未创建窗口,则 Handle
属性为 IntPtr.Zero
(null) .
在尝试访问句柄之前,我尝试在窗口上调用 this.Show()
和 this.Hide()
. 然后我可以拿到手柄,但是窗口上的窗口瞬间闪烁(丑陋!) .
有谁知道强制创建WPF窗口的方法?在Windows窗体中,这就像访问 Form.Handle
属性一样简单 .
Edit: 我最终选择了Chris Taylor的答案 . 在这里它是,如果它帮助其他人:
static void InitializeWindow(Window window)
{
// Get the current values of the properties we are going to change
double oldWidth = window.Width;
double oldHeight = window.Height;
WindowStyle oldWindowStyle = window.WindowStyle;
bool oldShowInTaskbar = window.ShowInTaskbar;
bool oldShowActivated = window.ShowActivated;
// Change the properties to make the window invisible
window.Width = 0;
window.Height = 0;
window.WindowStyle = WindowStyle.None;
window.ShowInTaskbar = false;
window.ShowActivated = false;
// Make WPF create the window's handle
window.Show();
window.Hide();
// Restore the old values
window.Width = oldWidth;
window.Height = oldHeight;
window.WindowStyle = oldWindowStyle;
window.ShowInTaskbar = oldShowInTaskbar;
window.ShowActivated = oldShowActivated;
}
// Use it like this:
InitializeWindow(myWpfWindow);
4 回答
一种选择是将窗口状态设置为最小化,而不是在显示窗口之前显示在任务栏中 . 尝试这样的事情 .
使用WindowInteropHelper.EnsureHandle,它完全符合您的需要 .
如果WindowInteropHelper的句柄为NULL,我正在寻找解决方案 . 希望这篇文章提供了一些如何解决它的其他信息 .
一种解决方案是使用:
这仅适用于.NET Framework 4 .
目前我正在使用.NET Framework 3.5,所以我需要另一种解决方案 . 然后我找到了一个带有WindowInteropHelper扩展方法的论坛帖子:
WindowInteropHelper.EnsureHandle()不期望已经创建了一个窗口 .
我遇到了同样的问题并且使用J Pollack's answer(因为它对我来说似乎更干净),但需要在.NET运行时2.0和4.0上运行的东西 .
但是当我这样做时,我最终得到了一个丑陋的MissingMethodException因为.NET运行时4.0中不再存在 SafeCreateWindow . 为了使代码在两个运行时都能工作,我决定捕获MissingMethodException并在.NET 4.0运行时调用等效代码,如下所示:
这允许我使用.NET 3.5编译代码,但是在安装了更高运行时版本的系统(即Windows 8及更高版本)上的.NET运行时4.0上运行它 .