【问题标题】:WinForms main window handleWinForms 主窗口句柄
【发布时间】:2013-11-11 05:59:45
【问题描述】:

在我的 winforms 应用程序中,我试图获取一个主窗口句柄,因此我可以将其设置为我的 wpf 模态窗口的父级。我对winforms不太熟悉,所以经过一番谷歌搜索后,我找到了两种方法来获得它。

  1. System.Windows.Forms.Application.OpenForms[0].Handle
    
  2. System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle
    

(1) 似乎总是返回看起来正确的相同值(至少我的模态窗口的行为符合预期),而 (2) 有时返回与 (1) 相同的值,但有时 - 一个完全不同的指针,这似乎不起作用(我的模式窗口出现在所有其他窗口的顶部,而不仅仅是父窗口)。

谁能解释这两种方法的区别?有时它们返回不同的结果是否正常?

编辑:

如果其他人想知道:一旦你得到了句柄,你可以通过创建WindowInteropHelper 类来使用它:

public static void SetInteropParent(this Window wpfDialogWindow, IntPtr winformsParentHandle)
{
    new WindowInteropHelper(wpdDialogWindow) { Owner = winformsParentHandle }; 
}  

【问题讨论】:

  • @JMK,我必须在我的主窗体上按下一个按钮才能显示一个模式窗口,所以我认为可以安全地假设活动窗口总是相同的。
  • 不能用Form.Handle吗?
  • @MPatel,我手头没有参考资料。而且我不想注入它。

标签: c# winforms window-handles


【解决方案1】:

Process.MainWindowHandle 返回错误的句柄当然很正常。 Process 类必须猜测哪个窗口是“主”窗口。本机 winapi 中没有指定窗口的机制。所以 Process 猜测 first 窗口是主窗口。这对于在使用启动画面或登录对话框等或在另一个线程上创建窗口的应用程序中出错的诀窍。

Application.OpenForms 没有这个问题,但是有一个失败模式,它会在重新创建一个窗口时失去对它的跟踪。当程序更改只能在创建窗口时指定的窗体的某些属性时,就会发生这种情况。 ShowInTaskbar、TransparencyKey 和 Opacity 属性是最常见的麻烦制造者。

最可靠的方法是重写你想成为父窗体的 OnHandleCreated() 方法。每当 Handle 属性更改时都会调用它。请注意,您要确保在 WPF 窗口处于活动状态时不会发生这种情况,这也会杀死 WPF 窗口。否则当然很容易观察:)

    protected override void OnHandleCreated(EventArgs e) {
        base.OnHandleCreated(e);
        SetWpfInteropParentHandle(this.Handle);
    }

【讨论】:

  • SetWpfInteropParentHandle 是如何实现的?
  • 你得问问 OP,他没有发布他的代码。
猜你喜欢
  • 2010-09-21
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
  • 2017-10-02
  • 1970-01-01
  • 1970-01-01
  • 2015-02-17
相关资源
最近更新 更多