2012-11-14 16 views
6

Sto cercando un modo per incorporare le applicazioni Windows Form scritte in C# in un'applicazione Windows C++. La finestra principale dell'applicazione nativa è suddivisa in diversi riquadri. L'app C# dovrebbe apparire all'interno di uno di quei riquadri, cioè la finestra radice del componente C# (il modulo più esterno) deve essere una finestra secondaria dell'applicazione principale.Windows Form come finestra secondaria di un'app non gestita

Questo può essere fatto? Se é cosi, come?

Un contesto aggiuntivo: per quanto ne so, ci sono due modi per farlo. Per prima cosa, ospitare il CLR nell'app nativa usando le API di hosting .net (ICLRRuntimeHost, ecc.). In secondo luogo, ospitare il CLR inserendo il modulo di Windows in un controllo ActiveX.

Per quanto riguarda il primo approccio, sono riuscito a far partire il CLR e caricare un assembly C# (grazie in gran parte a Mattias Högström). Dove sto colpendo un blocco stradale è che non vedo in alcun modo come dire al componente che sto correndo nel CLR che deve essere un figlio di una finestra passata dal lato C++.

Ho anche sperimentato il secondo metodo (utilizzando ActiveX e grazie a Daniel Yanovsky). Quasi, ma solo quasi, funziona per i miei scopi. Posso lasciare che i componenti arbitrari di Windows Form vengano eseguiti in un riquadro secondario dell'app nativa. MA funzionano sempre sul thread principale dell'app principale. Ciò significa che usano il ciclo dei messaggi di Windows dell'app principale. MSDN dice che questo non funzionerà in modo affidabile poiché i loop di messaggi standard di Windows non soddisfano i requisiti di Windows Form (volevo pubblicare qui il link a MSDN ma ho già utilizzato il mio nuovo utente-two-link-allotment).

Le eccezioni al problema del loop di messaggi sono, secondo MSDN, Internet Explorer e le app MFC. L'app nativa che sto usando come host non è sicuramente Internet Explorer. Inoltre, usa l'API di Windows come avvolto da wxWidgets, quindi l'opzione MFC non è (o almeno non è un benvenuto).

Le soluzioni proposte da Microsoft prevedono che i componenti C# vengano eseguiti nei propri loop di messaggi sui propri thread. Questo, almeno per quanto posso dire, riconduce necessariamente al primo approccio sopra menzionato. Quindi sono tornato alla domanda di far funzionare Windows Form sotto una finestra genitore passata.

Ancora una volta, sono interessato a qualsiasi input che chiarisca il problema della finestra secondaria, indipendentemente dagli approcci che ho menzionato qui. Ma alla luce del contesto ho potuto ridurre la questione generale a due domande specifiche (e avrei bisogno di una risposta ad uno solo di essi):

  • Dato un Windows Form ospitato in un controllo ActiveX, come posso permettere il modulo da eseguire nel proprio loop di messaggi sul proprio thread?

o

  • Dato un Windows Form in esecuzione in un CLR ospitato da un'applicazione nativa, come posso fare la forma sia una finestra secondaria di una finestra nella applicazione nativa?
+0

Sei riuscito a capirlo? Inoltre, qual è il link a quell'articolo di msdn? –

+0

Non dovresti aver bisogno di ActiveX per questo. Cosa succede quando chiami modulo. Come? È possibile passare una finestra IWin32Window (implementare questa interfaccia restituendo l'handle della finestra C++) come proprietario e inoltre si è a conoscenza della potente API SetParent: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633541 (v = vs.85) .aspx –

+0

Grazie per le risposte. @ Dinis Cruz: Questo è il [collegamento msdn] (http://msdn.microsoft.com/en-us/library/ms229600.aspx). @Simon Non ho sperimentato con l'impostazione del genitore perché non ero a conoscenza del fatto che Windows Forms offrisse quell'opzione e che potesse trattare in modo efficace con un genitore nativo. Credo di dover dare un'occhiata da vicino a IWin32Window. A causa dei limiti di tempo, abbiamo dovuto mettere questo in secondo piano per un po '. Spero di tornare ad esso all'inizio del 2013. Inizierò con il tentativo di impostare un genitore nativo della finestra nel contesto dell'hosting del CLR e pubblicheremo come sono andate le cose. – user1824048

risposta

1

sì, può essere fatto. Abbiamo fatto la stessa cosa anni fa. Questo è il nostro approccio: il controllo .NET ha anche un handle nativo della finestra, otteniamo questi handle tramite C++/CLI e li passiamo a Win32 e aggiungiamo questi handle come figli delle finestre native. Quindi i controlli .NET vengono eseguiti sul thread principale dell'app principale, la parte problematica è il loop dei messaggi, come hai menzionato nella tua domanda. Abbiamo bisogno di instradare il messaggio tra la nazione e .NET windows se necessario. Come ricordavo, abbiamo risolto molti bug relativi a questo problema, eppure c'erano ancora dei misteriosi problemi che non avevamo individuato.

C'è un altro modo: utilizzare l'interoperabilità WPF. http://msdn.microsoft.com/en-us/library/ms742522.aspx. Secondo MS, questo dovrebbe risolvere i problemi del messaggio, ma non abbiamo provato questo approccio. È sufficiente utilizzare Win32 per ospitare WPF, quindi utilizzare WPF per ospitare Winform.

Così per gli ultimi 2 domande:

  1. Non è possibile. Solo un ciclo di messaggi.
  2. Utilizzare la maniglia. Questo articolo parla dell'handle di Windows Form: http://blogs.msdn.com/b/jfoscoding/archive/2004/11/24/269416.aspx
+0

L'articolo su 2. è molto interessante. Sono più una persona win32/C++ e spesso non sono sicuro di quanto strettamente tutti gli elementi .net siano collegati all'universo sottostante (?) Win32. L'articolo punta nella direzione di: una forma è ancora molto una finestra. Quando andrò avanti, partirò dal punto di vista privilegiato per cercare di trattare il modulo come una finestra secondaria "normale" e quindi sperare che il CLR non implodi. – user1824048