2012-11-14 3 views
6

Ich bin auf der Suche nach einer Möglichkeit zum Einbetten von Windows Forms-Anwendungen in C# in einer C++ - Windows-Anwendung geschrieben. Das Hauptfenster der nativen Anwendung ist in mehrere Bereiche unterteilt. Die C# -App soll in einem dieser Bereiche erscheinen, d.h. das Wurzelfenster der C# -Komponente (der äußersten Form) muss ein untergeordnetes Fenster der Hauptanwendung sein.Windows Form als untergeordnetes Fenster einer nicht verwalteten App

Kann dies getan werden? Wenn das so ist, wie?

Einige zusätzliche Kontext: Nach meinem Wissen gibt es zwei Möglichkeiten, dies zu tun. Hosten Sie die CLR zunächst in der nativen App mithilfe der .net-Hosting-APIs (ICLRRuntimeHost usw.). Zweitens hosten Sie die CLR, indem Sie das Windows-Formular in ein ActiveX-Steuerelement einfügen.

In Bezug auf den ersten Ansatz, ich habe es geschafft, die CLR gestartet und laden eine C# -Aufbau (Dank weitgehend Mattias Högström). Wo ich eine Straßensperre treffe, sehe ich keine Möglichkeit, der Komponente, die ich in der CLR verwende, zu sagen, dass sie ein untergeordnetes Fenster eines von der C++ - Seite übergebenen Fensters sein muss.

Ich habe auch mit der zweiten Methode experimentiert (mit ActiveX und dank Daniel Yanovsky). Es funktioniert fast, aber nur fast, für meine Zwecke. Ich kann beliebige Windows Forms-Komponenten in einem untergeordneten Bereich der nativen App ausführen lassen. ABER sie laufen immer auf dem Hauptthread der Haupt-App. Dies bedeutet, dass sie die Windows-Nachrichtenschleife der Haupt-App verwenden. MSDN sagt, dass dies nicht zuverlässig funktionieren wird, da die Standard-Windows-Nachrichtenschleifen nicht die Anforderungen von Windows Forms erfüllen (Ich wollte hier den Link zu MSDN posten, aber habe bereits meine new-user-two-link-Zuteilung aufgebraucht).

Die Ausnahmen für das Nachrichtenschleifenproblem sind laut MSDN Internet Explorer und MFC-Anwendungen. Die native App, die ich als Host verwende, ist definitiv kein Internet Explorer. Außerdem verwendet es die Windows-API als von WxWidgets umschlossen, so dass MFC keine (oder zumindest keine willkommene) Option ist.

Die von Microsoft vorgeschlagenen Lösungen beziehen sich darauf, die C# -Komponenten in ihren eigenen Nachrichtenschleifen auf ihren eigenen Threads laufen zu lassen. Dies führt, zumindest soweit ich das beurteilen kann, notwendigerweise zu dem oben erwähnten ersten Ansatz. Also bin ich zurück zu der Frage, ein Windows-Formular zu erhalten, um in einem übergeführten übergeordneten Fenster zu arbeiten.

Noch einmal, ich bin an jeder Eingabe interessiert, die das Kind Fenster Problem klärt, unabhängig von den Ansätzen, die ich hier erwähnt habe. Doch angesichts des Kontextes konnte ich die allgemeine Frage auf zwei konkrete Fragen reduzieren (und ich würde nur eine von ihnen eine Antwort benötigen):

  • Bei einem Windows Form in einem ActiveX-Steuerelement gehostet wird, wie kann ich zulassen das Formular, um in einer eigenen Nachrichtenschleife in einem eigenen Thread zu laufen?

oder

  • ein Windows Form gegeben in einer CLR läuft durch eine native App gehostet, wie kann ich die Form, in der nativen App ein untergeordnetes Fenster eines Fensters sein?
+0

Haben Sie es geschafft, dies herauszufinden? Auch was ist der Link zu diesem msdn Artikel? –

+0

Sie sollten ActiveX dafür nicht benötigen. Was passiert, wenn Sie form.Show aufrufen? Sie könnten ein IWin32Window (implementieren Sie diese Schnittstelle, die das C++ - Fenster-Handle zurückgibt) als Besitzer übergeben und kennen Sie auch die leistungsstarke SetParent-API: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633541 (v = vs.85) .aspx –

+0

Vielen Dank für Ihre Antworten. @ Dinis Cruz: Dies ist der [MSDN-Link] (http://msdn.microsoft.com/en-us/library/ms229600.aspx). @Simon Ich habe nicht mit der Einstellung der Eltern experimentiert, weil mir nicht bewusst war, dass Windows Forms diese Option bietet und robust mit einem nativen Elternteil umgehen kann. Ich denke, ich muss IWin32Window genau unter die Lupe nehmen. Aus Zeitgründen mussten wir dies ein wenig auf Sparflamme setzen. Ich hoffe, dass ich Anfang 2013 wieder darauf zurückkommen werde. Ich werde damit beginnen, im Kontext des Hosting der CLR einen nativen Windows-Elternteil zu erstellen und zu veröffentlichen, wie die Dinge gelaufen sind. – user1824048

Antwort

1

ja, es kann getan werden. Das Gleiche haben wir vor Jahren gemacht. Das ist unser Ansatz: Die .NET-Steuerung hat auch ein natives Fenster-Handle, wir bekommen diese Handles durch C++/CLI und geben sie an Win32 weiter und fügen diese Handles als untergeordnete Elemente von nativen Fenstern hinzu. Die .NET-Steuerelemente werden also im Hauptthread der Hauptanwendung ausgeführt, der problematische Teil ist die Nachrichtenschleife, wie Sie in Ihrer Frage erwähnt haben. Wir müssen die Nachricht bei Bedarf zwischen der Nation und den .NET-Fenstern weiterleiten. Wie ich mich erinnerte, haben wir eine Menge Bugs behoben, die damit zusammenhingen, und trotzdem gab es ein mysteriöses Problem, das wir nicht herausgefunden hatten.

Es gibt einen anderen Weg: Verwenden von WPF Interop. http://msdn.microsoft.com/en-us/library/ms742522.aspx. Laut MS sollte dies die Nachrichtenprobleme beheben, aber wir haben diesen Ansatz nicht versucht. Sie können Win32 einfach zum Hosten von WPF verwenden und dann WPF als Host für WinForm verwenden.

Also für Ihre letzten 2 Fragen:

  1. können Sie nicht. Nur eine Nachrichtenschleife.
  2. Griff verwenden. Dieser Artikel behandelt das Handle von Windows Forms: http://blogs.msdn.com/b/jfoscoding/archive/2004/11/24/269416.aspx
+0

Der Artikel zu 2. ist sehr interessant. Ich bin eher eine win32/C++ - Person und oft unsicher, wie eng alle .net-Elemente mit dem darunterliegenden (?) Win32-Universum zusammenhängen. Dieser Artikel zeigt in die Richtung: Eine Form ist immer noch sehr ein Fenster. Wenn ich damit fortfahre, werde ich von dem Standpunkt aus beginnen, die Form nur als "normales" Kindfenster zu behandeln und dann zu hoffen, dass die CLR nicht implodiert. – user1824048

Verwandte Themen