2012-11-14 113 views
6

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

可以这样做吗?如果是这样,怎么样?

一些额外的背景:据我所知,有两种方法可以解决这个问题。首先,使用.net托管API(ICLRRuntimeHost等)在本地应用程序中托管CLR。其次,通过将窗体放入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不是(或者至少不是一个受欢迎的)选项。

微软建议的解决方案包括让C#组件在其自己的线程中运行自己的消息循环。至少据我所知,这一定会回到上述第一种方法。所以我回到了让Windows窗体在传入的父窗口下工作的问题。

同样,我对澄清子窗口问题的任何输入都感兴趣,这与我在此提及的方法无关。但根据上下文我可以在一般的问题减少到两个具体问题(我需要一个答案,其中只有一个):

  • 鉴于ActiveX控件托管的Windows窗体,我怎样才能让表单在自己的线程中运行在自己的消息循环中?

  • 鉴于通过本机应用程序托管的CLR上运行的Windows窗体,我怎样才能使形式是窗口的子窗口中的本机应用程序?
+0

您是否设法弄清楚了这一点?那个msdn文章的链接是什么? –

+0

您不应该为此需要ActiveX。当你打电话给form.Show时会发生什么?你可以通过一个IWin32Window(实现这个接口返回C++窗口句柄)作为所有者,你也知道强大的SetParent API:http://msdn.microsoft.com/en-us/library/windows/desktop/ms633541( v = vs.85).aspx –

+0

感谢您的回复。 @ Dinis Cruz:这是[msdn链接](http://msdn.microsoft.com/en-us/library/ms229600.aspx)。 @Simon我没有尝试设置父项,因为我不知道Windows窗体提供了这个选项,并且可以稳健地处理本地父项。我想我需要仔细看看IWin32Window。由于时间的限制,我们不得不把这个放在一旁。我希望在2013年初回到它。我将首先尝试在托管CLR的环境中设置本地窗口父级,并将发布事件的实现方式。 – user1824048

回答

1

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

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

因此,对于你最后的2个问题:

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

2.的文章很有意思。我更像是一个win32/C++人,并且常常不确定所有.net元素与基础(?)win32 Universe的关系。那篇文章指出:形式仍然是一个窗口。当我继续讨论这个问题时,我将从试图将窗体视为“正常”子窗口的角度出发,然后希望CLR不会崩溃。 – user1824048

相关问题