IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Contribuez C++ Discussion :

[FAQ VC++]Comment héberger des Windows Forms Controls dans des vues MFC?


Sujet :

Contribuez C++

  1. #1
    Membre éprouvé
    Avatar de Gabrielly
    Inscrit en
    Juin 2004
    Messages
    722
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 722
    Points : 1 128
    Points
    1 128
    Par défaut [FAQ VC++]Comment héberger des Windows Forms Controls dans des vues MFC?
    Soient des composants .NET faisant partis du namespace System.Windows.Forms comme une listview .NET ou un webbrowser .NET ou un DataGridView .NET ou un ReportViewer .NET et montrons comment nous pouvons les héberger dans une vue MFC dans un modèle SDI ou MDI.

    Créeons une solution MFC Hosting contenant trois projets :

    1. Un Projet C++/CLI HostingWinFormsControls Windows Forms Control Library
    2. Un Projet DLL MfcWinFormsHostDll Dll d'extension MFC
    3. Un Projet Exe MfcWinFormsHost Application MFC MDI

    Dans le projet HostingWinFormsControls nous allons ajouter plusieurs user control pour chacun des composants .NET en oubliant pas de faire Dock in Parent Container de façon à remplir la surface de chacun de nos User Control

    Dans le projet MfcWinFormsHostDll nous allons montrer comment une dll d'extension MFC peut hoster des contrôles .NET et illustrer ainsi l'exportation des classes C++ dans une application MFC

    Le projet MfcWinFormsHost peut hoster les contrôles .NET de 2 façons. Soient par sa dll d'extension MfcWinFormsHostDll ou directement à partir du User Control HostingWinFormsControls.

    Pour le cas d'un DataGridView le code généré est le suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public ref class HostingWinFormsControlsControl : public System::Windows::Forms::UserControl
    	{
    	public:
    		HostingWinFormsControlsControl(void)
    		{
    			InitializeComponent();
    			//
    			//TODO: Add the constructor code here
    			//
    		}
    
    	// ...
    	private: System::Windows::Forms::DataGridView^  dataGridView1;
    	// ...
    Maintenant il est question que ce usercontrol soit connecté à l'infrastructure des MFC. Nous allons entamer les étapes suivantes.

    Pour le projet HostingWinFormsControls
    1. Modifier la classe de base de chacun de nos user control comme ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    	public ref class HostingWinFormsControlsControl : public System::Windows::Forms::UserControl
    				, public Microsoft::VisualC::MFC::ICommandTarget 
    				, public Microsoft::VisualC::MFC::IView
    	{
    2. Implémenter les méthodes virtualles commec cela
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
    private:
    		Microsoft::VisualC::MFC::ICommandSource^ m_CmdSrc; // need ID of control in MFC dialog and callback function
     
    	public:
    		virtual void Initialize(Microsoft::VisualC::MFC::ICommandSource^ cmdSrc)
    		{
                                          // Pour connecter les messages command avec votre CWinFormsViews
    		   	m_CmdSrc = cmdSrc;
    			//m_CmdSrc->AddCommandHandler(ID_COMMAND1, gcnew CommandHandler(this, &WpfUserControlHostControl::OnMethod1));
    			//m_CmdSrc->AddCommandHandler(ID_COMMAND2, gcnew CommandHandler(this, &WpfUserControlHostControl::OnMethod2));
    			//m_CmdSrc->AddCommandHandler(ID_COMMAND3, gcnew CommandHandler(this, &WpfUserControlHostControl::OnMethod3));
    		}
     
    		virtual void OnInitialUpdate()
    		{   
    		   // Le OnInitialUpdate de CWinFormsView() appelle cette méthode ci
     
    		}
     
    		virtual void OnUpdate()
    		{
                                  // Le OnUpdate de CWinFormsView() appelle cette méthode ci
     
    		}
     
    		virtual void OnActivateView(bool activate)
    		{
                                    // Lors que votre CWinFormsView() est activée
    		}
    3. Il faut ensuite référencer l'assemblie MFCMIFC80.dll dans le projet HostingWinFormsControlsControl qui se trouve typiquement dans le répertoire d''installation de votre Visual Studio (VS 2010 chez moi ) soit $(VsInstallDir)VC\atlmfc\lib\MFCMIFC80.dll

    Pour le projet MfcWinFormsHostDll
    4. Ajouter une classe MFC qui dérive de CView en l'appelant CMfcDataGridView. Ensuite remplacer toutes les occurences de CView en CWinFormsView
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    class AFX_EXT_CLASS CMfcDataGridView : public CWinFormsView
    {
    	DECLARE_DYNCREATE(CMfcDataGridView)
    
    protected:
    	CMfcDataGridView();           // protected constructor used by dynamic creation
    	virtual ~CMfcDataGridView();
    
    public:
    	virtual void OnDraw(CDC* pDC);      // overridden to draw this view
    #ifdef _DEBUG
    	virtual void AssertValid() const;
    #ifndef _WIN32_WCE
    	virtual void Dump(CDumpContext& dc) const;
    #endif
    #endif
    
    protected:
    	DECLARE_MESSAGE_MAP()
    };
    N'oubliez de mettre la macro AFX_EXT_CLASS devant CMfcDataGridView car elle sera exportée depuis notre Dll d'extension MFC MfcWinFormsHostDll. La classe de base doit être la CWinFormsView.

    5. Ajouter une petite méthode très utilitaire dans notre classe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    class AFX_EXT_CLASS CMfcDataGridView : public CWinFormsView
    { 
                //...
                // Attributes
    public:
    	gcroot<HostingWinFormsControls::HostingWinFormsControlsControl^> GetDataGridControl() const;
    -> L'idée ici est que la CListView a son GetListCtrl(), la CTreeView a son GetTreeCtrl(), et donc notre CMfcXXXView a son GetXXXCtrl()

    -> Lorsque des données membres d'une classe sont définies, ou bien certains argument ou type de retour de méthodes, les classes natives imposent à ce que les membres managés soit vêtu en toute transparence par des gcroot<>.

    6. Dans le fichier source de MfcDataGridView.cpp on a :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CMfcDataGridView::CMfcDataGridView()
             :CWinFormsView(HostingWinFormsControls::HostingWinFormsControlsControl::typeid)
    {
    
    }
    C'est dans le constructeur que l'on définit notre type de vue

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    gcroot<HostingWinFormsControls::HostingWinFormsControlsControl^> CMfcDataGridView::GetDataGridControl() const
    {
    	return static_cast<HostingWinFormsControls::HostingWinFormsControlsControl^>(CWinFormsView::GetControl());
    }
    Et voici l'implémentation de notre GetXXXControl()

    7. Il faut référencer le projet HostingWinFormsControls dans MfcWinFormsHostDll
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    // dans le StdAfx.h de MfcWinFormsHostDll
    // ...
     
    #if defined(__cplusplus_cli)
     
    #include <vcclr.h>
    #include <afxwinforms.h>   // MFC Windows Forms support
     
    #using <HostingWinFormsControls.dll>
    #endif
    8. Configurer votre dll d'extension pour qu'elle support le runtime .NET
    [FAQ VC++]Comment ajuster les settings de ses projets MFC pour supporter des composants .NET.

    9. Préparer votre dll afin que ses objets (fichier *.h, *.lib) soit correctement exportable et vue des autres modules.
    [FAQ VC++]Comment exploiter efficacement l'exportation des classes C++
    En final on doit avoir le fichier MfcWinFormsHostDll.h et la librairie MfcWinFormsHostDll.lib
    Le fichier MfcWinFormsHostDll.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    #pragma once
    
    #include "MfcDataGridView.h"
    La sortie de la librairie MfcWinFormsHostDll.lib
    Propriétés du projet MfcWinFormsHostDll > Configuration Properties > Linker > Advanced > Import Library : $(SolutionDir)$(Configuration)\$(TargetName).lib

    Pour le projet MfcWinFormsHost
    10. Pour la classe CMfcWinFormsHostView remplacer toutes les occurences de sa classe de base CView par CMfcDataGridView
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    class CMfcWinFormsHostView : public CMfcDataGridView
    11. Dans le fichier stdAfx de MfcWinFormsHost on référence le projet MfcWinFormsHostDll
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    // le fichier stdAfx de MfcWinFormsHost
     
    #if defined(__cplusplus_cli)
     
    #include <vcclr.h>
    #include <afxwinforms.h>   // MFC Windows Forms support
     
    #using <HostingWinFormsControls.dll>
    #endif
     
    #include "..\MfcWinFormsHostDll\MfcWinFormsHostDll.h"
    Puis Propriétés du projet MfcWinFormsHost > Configuration Properties > C/C++ > General > Resolve #using References : $(SolutionDir)$(Configuration)\

    12. Il faut référencer la librairie MfcWinFormsHostDll.lib dans le projet MfcWinFormsHost

    Propriétés du projet MfcWinFormsHost > Configuration Properties > Linker > Input > Additional Dependencies : MfcWinFormsHostDll.lib
    Propriétiés du projet MfcWinFormsHost > Configuration Properties > VC++ Directories > Librairies Directories : on ajoute $(SolutionDir)$(Configuration)\;


    Bon on compile toute la solution et on obtient une application comme celle-ci



    Les DataGridView de DotNet sont pour l'instant vide. Il suffit de les remplir en fournissant par exemple le DataSource qui est attaché au control interne DataGridView.

    Pour travailler avec votre control vous avez la méthode CMfcWinFormsHostView::GetDataGridControl() de la vue de votre exe car
    CMfcWinFormsHostView dérive de CMfcDataGridView de votre dll MFC et CMfcDataGridView embarque son contrôle interne gcroot<HostingWinFormsControls::HostingWinFormsControlsControl^>

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    void CUneClassDuProjetMfcWinFormsHost::SomeMethod(CDocument* pDoc)
    {
    	POSITION pos = pDoc->GetFirstViewPosition();
    	CMfcWinFormsHostView* pView = static_cast<CMfcWinFormsHostView*>(pDoc->GetNextView(pos));
    	HostingWinFormsControls::HostingWinFormsControlsControl^ pUserControl = pView->GetDataGridControl();
     
    	System::Windows::Forms::DataGridView^ pDataGridView = pUserControl->dataGridView1;
     
                // bon je travaille avec mon DataGridView
               // ....
    }
    Remarquez que pour obtenir ce résultat il suffit d'avoir bien maîtriser les 2 points ci dessous:
    1. [FAQ VC++]Comment exploiter efficacement l'exportation des classes C++

    2. [FAQ VC++]Comment ajuster les settings de ses projets MFC pour supporter des composants .NET.

    Voilà

  2. #2
    Membre éprouvé
    Avatar de Gabrielly
    Inscrit en
    Juin 2004
    Messages
    722
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 722
    Points : 1 128
    Points
    1 128
    Par défaut
    Idem pour les webbrowser .NET hoster dans des childframes MFC
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    namespace HostingWinFormsControls {
    
    	/// <summary>
    	/// Summary for UserWebBrowserControl
    	/// </summary>
    	public ref class UserWebBrowserControl : public System::Windows::Forms::UserControl
    				, public Microsoft::VisualC::MFC::ICommandTarget 
    				, public Microsoft::VisualC::MFC::IView
    	{
    //...
    virtual void OnInitialUpdate()
    		{   
    		   // Le OnInitialUpdate de CWinFormsView() appelle cette méthode ci
    
    			webBrowser1->Navigate("www.developpez.com");
    		}
    //...



Discussions similaires

  1. Réponses: 2
    Dernier message: 27/06/2007, 11h42
  2. [Winforms]esthétique des windows form
    Par souaddemaroc dans le forum Général Dotnet
    Réponses: 5
    Dernier message: 03/04/2006, 20h38
  3. Réponses: 11
    Dernier message: 10/03/2006, 17h56
  4. A propos des Windows Forms
    Par sheitan dans le forum C++
    Réponses: 2
    Dernier message: 13/02/2006, 20h54
  5. Pointeur sur des windows form
    Par durans dans le forum MFC
    Réponses: 1
    Dernier message: 03/02/2006, 16h27

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo