如何将未托管的对话框设置为 WinForm 窗体的所有者?

7

我需要获取一个WinForm对话框所有者的HWND。在非托管代码中,我有一个后台线程,用于获取前端窗口的HWND。然后,代码调用:: GetParent(frontHWND)以查看是否需要隐藏不同的非模态MFC对话框。当WinForm对话框是frontHWND时,我总是得到GetParent调用的NULL返回值。我还尝试了GetOwner,意识到.Net试图清除Parent和Owner之间的区别。通过使用Spy++查看WinForm对话框,它也表示WinForm没有父级或所有者。我已经传入了:

NativeWindow ^natWin = gcnew NativeWindow();
natWin->AssignHandle(IntPtr(hwndParent));
managedDlg->ShowDialog(natWin);

上面的代码没有设置WinForm的所有者。 我尝试在OnFormShown()中从WinForm代码中调用Win32 SetParent,但这会锁定MFC应用程序和WinForm。

有人能解释一下如何使我的非托管对话框/应用程序成为托管winform的所有者/父窗口吗?


任何信息都将是有帮助的...例如ShowDialog(IWin32Window)实际设置了什么。根据这个链接,link,它应该设置所有者,但当我使用Spy++时,我没有看到那个。 - Byron
1个回答

5
为了在一个C++父窗口中显示C#窗体,我可以这样做:
void GUIWrapper(HWND parent)
{
    System::IntPtr myWindowHandle = System::IntPtr(parent);
    System::Windows::Forms::IWin32Window ^w = System::Windows::Forms::Control::FromHandle(myWindowHandle);
    ManagedDialog::ManagedDialogGUI ^d = gcnew ManagedDialog::ManagedDialogGUI();
    d->Show(w);
}

这段代码需要放在C++/CLI包装器DLL中。

编辑:“w”必须与nullptr进行比较,因为Control::FromHandle可能会失败。请参见此处: 为什么Control.FromHandle(IntPtr)在一个被挂钩的进程中返回null,在另一个被挂钩的进程中返回“Form”的有效对象?

因此,安全的代码应该是:

    if (w == nullptr)
        d->Show();
    else
        d->Show(w);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接