C# WinForms主窗口句柄

C# WinForms主窗口句柄,c#,winforms,window-handles,C#,Winforms,Window Handles,在我的winforms应用程序中,我试图获取一个主窗口句柄,以便将其设置为wpf模式窗口的父窗口。我对winforms不是很有经验,所以在谷歌搜索了一下之后,我找到了两种方法来获得它 (1) 似乎总是返回看起来正确的相同值(至少我的模式窗口的行为符合预期),而(2)有时返回与(1)相同的值,但有时-一个完全不同的指针,它似乎不起作用(我的模式窗口显示在每个其他窗口的顶部,而不仅仅是父窗口) 有人能解释一下这两种方法的区别吗?有时它们会返回不同的结果,这正常吗 编辑: 如果其他人想知道:一旦获

在我的winforms应用程序中,我试图获取一个主窗口句柄,以便将其设置为wpf模式窗口的父窗口。我对winforms不是很有经验,所以在谷歌搜索了一下之后,我找到了两种方法来获得它

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

    有人能解释一下这两种方法的区别吗?有时它们会返回不同的结果,这正常吗

    编辑:

    如果其他人想知道:一旦获得句柄,您可以通过创建
    WindowInteropHelper
    class来使用它:

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

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

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

    最可靠的方法是重写要作为父级的表单的OnHandleCreated()方法。每当Handle属性更改时调用。请注意,您希望确保在WPF窗口处于活动状态时不会发生这种情况,这也会杀死WPF窗口。当然,在其他方面很容易观察:)


    @JMK,我必须按下主窗体上的一个按钮才能显示一个模式窗口,所以我认为可以安全地假设,活动窗口总是相同的。你不能使用form.Handle吗?@MPatel,我手头没有参考资料。我不想注入它。SetWpfInteropParentHandle是如何实现的?你必须问OP,他没有发布他的代码。
    System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle
    
    public static void SetInteropParent(this Window wpfDialogWindow, IntPtr winformsParentHandle)
    {
        new WindowInteropHelper(wpdDialogWindow) { Owner = winformsParentHandle }; 
    }  
    
        protected override void OnHandleCreated(EventArgs e) {
            base.OnHandleCreated(e);
            SetWpfInteropParentHandle(this.Handle);
        }