Modern C# Interop with MFC

A modern way to use pure .Net Components and Controls in MFC applications

Part 1.

.Net and MFC


Spiace sentire qua e là i detrattori di Microsoft Foundation Class Library ( MFC ) che son convinti che il framework C++ per Windows sia oramai al suo capolinea o quasi in quanto soppiantato da .Net; mentre non è affatto così; oggi, a tanti anni dal suo esordio, MFC apre ancora nuovi scenari ad una folta schiera di professionisti (e appassionati) che, all'occorrenza, usano il framework MFC.

Nel tempo Microsoft ha fatto in modo di accrescere sempre più l'interoperabilità tra MFC e gli altri frameworks, primo fra tutti il .Net (al momento arrivato alla versione 4.7) tant' è che oggi in una applicazione MFC è possibile far convivere MFC, appunto, e .Net in maniera efficace e molto più semplicemente rispetto al passato, quando la compatibilità era minore e chi voleva mixare managed code con unmanaged doveva passare spesso per COM e C++/CLI.

Naturalmente "l'unione" tra i frameworks .Net e MFC in un'applicazione MFC è possibile a patto che quest'ultima sia istruita per "comprendere" il managed code, cioè il managed C++.
Un progetto MFC può produrre un assembly .Net (managed C++) attivando la specifica funzionalità tra le impostazioni del progetto in Visual Studio.

Una volta attivata tale funzionalità, sarà anche possibile usare Components e UserControls scritti in uno dei linguaggi .Net ( C#, VB etc).
Ma com'è possibile utilizzare un componente od un controllo Windows Forms, magari scritto in C# e non registrato nella GAC, in un'applicazione MFC?

Tecnicamente la relazione tra un controllo utente .Net "ospitato" in una dialog MFC è molto simile a quella tra un ActiveX e la sua applicazione container: apparente, illusoria.
L'effetto che un controllo ActiveX e l'applicazione container che lo ospita danno, è quello di un oggetto "unico" e questo avviene perchè l'ActiveX e il suo container possono "comunicare" (in questo caso via COM) in maniera bidirezionale dando la sensazione che i due oggetti interagiscano. Ma è un'illusione, in realtà i due oggetti vivono di vita propria e non hanno alcuna relazione l'uno con l'altro, l'unica cosa che li unisce è, appunto, la possibilità di comunicare tra loro.
Allo stesso modo può essere vista la relazione tra un UserControl quando ospitato in una dialog MFC.

La classe MFC che consente l'inserimento di componenti e controlli .Net in una dialog (MFC) è
CWinFormsControl

template<TManagedControl>
class CWinFormsControl : public CWnd

Ed il relativo file #include:

#include <afxwinforms.h>

Il costruttore:

CWinFormsControl();

I metodi

CreateManagedControl(..);
     
GetControl();

GetControlHandle();

Il metodo CreateManagedControl ha 4 overloads


inline BOOL CreateManagedControl(
    System::Type^ pType,  
    DWORD dwStyle,  
    const RECT& rect,  
    CWnd* pParentWnd,  
    int nID)  


inline BOOL CreateManagedControl(
    DWORD dwStyle,  
    const RECT& rect,  
    CWnd* pParentWnd,  
    int nID);


inline BOOL CreateManagedControl(
    DWORD dwStyle,  
    int nPlaceHolderID,  
    CWnd* pParentWnd);


inline BOOL CreateManagedControl(
    typename TManagedControl^ pControl,  
    DWORD dwStyle,  
    const RECT& rect,  
    CWnd* pParentWnd,  
    int nID);




Giuseppe Pischedda 2018


Se il post ti è utile puoi fare una donazione all'autore, l'importo è a tua libera scelta.

Grazie