我需要访问一些WPF窗口的Win32窗口句柄,以便处理Win32激活消息。我知道我可以使用PresentationSource.FromVisual
或WindowInteropHelper
来获取Win32窗口句柄,但是如果还没有创建WPF窗口,我就会遇到问题。
如果我使用PresentationSource.FromVisual
,并且未创建窗口,则返回的PresentationSource
为null。如果我使用WindowInteropHelper
,且未创建窗口,则Handle
属性为IntPtr.Zero
(null)。
在尝试访问句柄之前,我尝试在窗口上调用this.Show()
和this.Hide()
。然后我就可以得到手柄,但是窗口在屏幕上瞬间闪烁(丑陋!)
有人知道如何强制创建WPF窗口吗?在Windows中,这与访问Form.Handle
属性一样简单。
编辑:,我最终使用了Chris的答案的一个变体。在这里,万一它能帮助到其他人:
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);
发布于 2010-07-10 11:49:09
一种选择是将窗口状态设置为最小化,在显示窗口之前不显示在任务栏中。试试这样的东西。
IntPtr hWnd;
WindowInteropHelper helper = new WindowInteropHelper(wnd);
WindowState prevState = wnd.WindowState;
bool prevShowInTaskBar = wnd.ShowInTaskbar;
wnd.ShowInTaskbar = false;
wnd.WindowState = WindowState.Minimized;
wnd.Show();
hWnd = helper.Handle;
wnd.Hide();
wnd.ShowInTaskbar = prevShowInTaskBar;
wnd.WindowState = prevState;
发布于 2011-01-28 01:42:44
使用WindowInteropHelper.EnsureHandle
,它可以完全满足您的需要。
发布于 2011-08-11 23:31:18
如果WindowInteropHelper的句柄为NULL,我正在寻找解决方案。希望这篇文章能提供一些更多的信息来解决这个问题。
一种解决办法是使用:
var window = new Window();
var handle = new WindowInteropHelper(window).EnsureHandle()
这仅适用于.NET框架4。
目前我正在使用.NET Framework3.5,所以我需要另一个解决方案。然后,我找到了一个带有WindowInteropHelper扩展方法的论坛线程:
#region
using System;
using System.Reflection;
using System.Windows;
using System.Windows.Interop;
#endregion
namespace System.Windows.Interop
{
/// <summary>
/// Provides NetFX 4.0 EnsureHandle method for
/// NetFX 3.5 WindowInteropHelper class.
/// </summary>
public static class WindowInteropHelperExtension
{
/// <summary>
/// Creates the HWND of the window if the HWND has not been created yet.
/// </summary>
/// <param name = "helper">An instance of WindowInteropHelper class.</param>
/// <returns>An IntPtr that represents the HWND.</returns>
/// <remarks>
/// Use the EnsureHandle method when you want to separate
/// window handle (HWND) creation from the
/// actual showing of the managed Window.
/// </remarks>
public static IntPtr EnsureHandle(this WindowInteropHelper helper)
{
if (helper == null)
throw new ArgumentNullException("helper");
if (helper.Handle == IntPtr.Zero)
{
var window = (Window) typeof (WindowInteropHelper).InvokeMember(
"_window",
BindingFlags.GetField |
BindingFlags.Instance |
BindingFlags.NonPublic,
null, helper, null);
typeof (Window).InvokeMember(
"SafeCreateWindow",
BindingFlags.InvokeMethod |
BindingFlags.Instance |
BindingFlags.NonPublic,
null, window, null);
}
return helper.Handle;
}
}
}
WindowInteropHelper.EnsureHandle()并不期望已经创建了一个窗口。
参考资料: Alexander http://social.msdn.microsoft.com/Forums/en-MY/wpf/thread/5f89ac58-d2ef-4ac0-aefb-b2826dbef48a
https://stackoverflow.com/questions/3220497
复制