【问题标题】:Windows Form as child window of an unmanaged appWindows 窗体作为非托管应用程序的子窗口
【发布时间】:2012-11-03 02:17:08
【问题描述】:

我正在寻找一种将用 C# 编写的 Windows 窗体应用程序嵌入到 C++ Windows 应用程序中的方法。本机应用程序主窗口被细分为几个窗格。 C# 应用程序应该出现在其中一个窗格中,即 C# 组件的根窗口(最外层窗体)必须是主应用程序的子窗口。

这可以吗?如果有,怎么做?

一些额外的背景:据我所知,有两种方法可以解决这个问题。首先,使用 .net 托管 API(ICLRRuntimeHost 等)在本机应用程序中托管 CLR。其次,通过将 Windows 窗体放在 ActiveX 控件中来承载 CLR。​​

关于第一种方法,我设法启动了 CLR 并加载了 C# 程序集(很大程度上感谢 Mattias Högström)。我遇到障碍的地方是,我看不出如何告诉我在 CLR 中运行的组件它需要是从 C++ 端传入的窗口的子级。

我还尝试了第二种方法(使用 ActiveX 并感谢Daniel Yanovsky)。它几乎,但只是几乎,适用于我的目的。我可以让任意 Windows 窗体组件在本机应用程序的子窗格中运行。但它们总是在主应用程序的主线程上运行。这意味着他们使用主应用程序的 Windows 消息循环。 MSDN 说这不会可靠地工作,因为标准的 Windows 消息循环不符合 Windows 窗体的要求(我想在这里发布到 MSDN 的链接,但已经用完了我的新用户两个链接分配)。

消息循环问题的例外情况是,根据 MSDN、Internet Explorer 和 MFC 应用程序。我作为主机使用的本机应用程序绝对不是 Internet Explorer。此外,它使用由 wxWidgets 包装的 windows API,因此 MFC 不是(或至少不是受欢迎的)选项。

Microsoft 提出的解决方案包括让 C# 组件在自己的线程上以自己的消息循环运行。至少据我所知,这必然会导致回到上面提到的第一种方法。所以我回到让 Windows 窗体在传入的父窗口下工作的问题。

再次,我对澄清子窗口问题的任何输入感兴趣,与我在这里提到的方法无关。但根据上下文,我可以将一般问题简化为两个具体问题(我只需要回答其中一个问题):

  • 给定一个托管在 ActiveX 控件中的 Windows 窗体,如何允许窗体在其自己的线程上以自己的消息循环运行?

  • 鉴于在本机应用程序托管的 CLR 中运行的 Windows 窗体,如何使窗体成为本机应用程序中窗口的子窗口?

【问题讨论】:

  • 你设法解决这个问题了吗?还有那个 msdn 文章的链接是什么?
  • 您不需要 ActiveX。当你调用 form.Show 时会发生什么?您可以将 IWin32Window(实现此接口返回 C++ 窗口句柄)作为所有者传递,并且您知道强大的 SetParent API:msdn.microsoft.com/en-us/library/windows/desktop/…
  • 感谢您的回复。 @Dinis Cruz:这是msdn link。 @Simon 我没有尝试设置父级,因为我不知道 Windows 窗体提供该选项并且可以与本地父级进行稳健处理。我想我需要仔细看看 IWin32Window。由于时间限制,我们不得不暂时搁置它。我希望在 2013 年初回到它。我将从尝试在托管 CLR 的上下文中设置本机窗口父级开始,并将发布事情的结果。

标签: c# c++ winapi clr


【解决方案1】:

是的,可以做到。几年前我们也做过同样的事情。这是我们的方法:.NET 控件也有原生窗口句柄,我们通过 C++/CLI 获取这些句柄并将它们传递给 Win32,并将这些句柄添加为原生窗口的子窗口。因此,.NET 控件在主应用程序的主线程上运行,有问题的部分是消息循环,正如您在问题中提到的那样。如果需要,我们需要在国家和 .NET 窗口之间路由消息。我记得,我们修复了很多与此相关的错误,但仍然有一些我们没有弄清楚的神秘问题。

还有另一种方法:使用 WPF 互操作。 http://msdn.microsoft.com/en-us/library/ms742522.aspx 。根据 MS 的说法,这应该可以解决消息问题,但我们没有尝试这种方法。您可以只使用 Win32 托管 WPF,然后使用 WPF 托管 Winform。

所以对于你的最后两个问题:

  1. 你不能。只有一个消息循环。
  2. 使用手柄。本文讲的是Windows Forms的句柄:http://blogs.msdn.com/b/jfoscoding/archive/2004/11/24/269416.aspx

【讨论】:

  • 2.的文章很有意思。我更像是一个 win32/C++ 人,并且经常不确定所有 .net 元素与底层(?)win32 宇宙的关系有多紧密。那篇文章指出的方向是:表单在很大程度上仍然是一个窗口。当我继续这一点时,我将从尝试将表单视为“正常”子窗口的有利位置开始,然后希望 CLR 不会内爆。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-18
  • 2021-02-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多