如何从 WPF 应用程序中获取 Windows Forms 使用的 IWin32Window Handle
本文提供了一个在不同窗口句柄之间进行转换的解决方法

引言
如果我们需要使用Windows窗体namespace
下的函数,可能会遇到窗口句柄不同的问题。本文需要解决的问题是如何将WPF中的System.Window
句柄转换为Windows窗体中的IWin32Window
。
背景
这里,我们只创建一个示例。Windows窗体消息框由WPF中的线程调用,并且需要模态状态。在这种情况下,需要IWin32Window
句柄来设置当前主窗口。
在一般的Windows窗体应用程序中,有一个名为MessageBox.Show
的函数,它可以弹出具有不同样式的消息框。
以下MessageBoxButton
常量定义在System.Windows.Forms
中
成员名称 | 描述 |
中止重试忽略 |
消息框包含**Abort**、**Retry**和**Ignore**按钮。 |
好的 |
消息框包含一个**OK**按钮。 |
确定取消 |
消息框包含**OK**和**Cancel**按钮。 |
重试取消 |
消息框包含**Retry**和**Cancel**按钮。 |
是/否 |
消息框包含**Yes**和**No**按钮。 |
是/否/取消 |
消息框包含**Yes**、**No**和**Cancel**按钮。 |
在WPF Windows namespace
中,也存在一个名为MessageBox.Show
的函数。但是,它具有不同的样式定义。
以下MessageBoxButton
常量定义在System.Windows
下
成员名称 | 描述 |
好的 |
消息框显示一个**OK**按钮。 |
确定取消 |
消息框显示**OK**和**Cancel**按钮。 |
确定取消 |
消息框显示**Yes**和**No**按钮。 |
是/否/取消 |
消息框显示**Yes**、**No**和**Cancel**按钮。 |
但有时,诸如AbortRetryIgnore
样式的消息框在应用程序开发中非常有用。但是,如果我们需要在多线程模型中使用具有**模态**状态的Windows窗体消息框,则需要IWin32Window
句柄而不是WPF窗口句柄。
Using the Code
以下代码可以帮助我们从WPF应用程序中获取IWin32Window
。
首先,我们可以从process
中获取一个作为IntPtr
的Windows句柄。之后,我们需要一个WindowWrapper
来将窗口句柄转换为IWin32Window
。
//Get FriendlyName from Application Domain
string strFriendlyName = AppDomain.CurrentDomain.FriendlyName;
//Get process collection by the application name without extension (.exe)
Process[] pro = Process.GetProcessesByName(
strFriendlyName.Substring(0, strFriendlyName.LastIndexOf('.')));
//Get main window handle pointer and wrap into IWin32Window
System.Windows.Forms.MessageBox.Show(
new WindowWrapper(pro[0].MainWindowHandle),
"Warning Message.", "Title",
MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Warning);
public class WindowWrapper : System.Windows.Forms.IWin32Window
{
public WindowWrapper(IntPtr handle)
{
_hwnd = handle;
}
public IntPtr Handle
{
get { return _hwnd; }
}
private IntPtr _hwnd;
}
历史
- 2007年9月5日:初始发布