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

Windows Discussion :

mélange managé / non-managé


Sujet :

Windows

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    82
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Décembre 2007
    Messages : 82
    Points : 89
    Points
    89
    Par défaut mélange managé / non-managé
    J'ai une application 'Windows' standard, écrite en C++ (sans usage de classes, donc en C ! ) dans l'une des boites de dialogue j'ai besoin d'afficher du HTML, j'ai renoncé à utiliser 'Chrome' et "Edge' dans leurs versions ad-hoc et me suis rabattu sur le WebControl inclus dans une 'form' ; je pensais gagner du temps ... C'était sans compter avec ma méconnaissance de l'embrigadement des "^".

    Voilà la fonction en question :

    Code C : 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
    31
    32
    #pragma managed
    #include "vue HTML.h"
     
     
    void VoirBranche(HWND idDlg,int code)
    {
    	char tpFic[1000];
    	RECT rect;
    	vueHTML ^ MaVue;
    	HWND visu;
     
    	switch(code)
    	{
    	case 1:
    		strcpy(tpFic, CheminArboFichier("", 1));                 // mes fonctions pour naviguer dans les répertoires de données de mon application
    		FaitChoixItemHTML(BrancheCourante, 1, tpFic);      // crée un fichier HTML avec diverses données qui sont dynamiquement envoyées à une adjonction Chrome/ Mozilla
     
    		visu = GetDlgItem(idDlg, BR_ST_VISU);                  // un contrôle dans la boite de dialogue ouverte
    		GetWindowRect(visu, &rect);
     
    		MaVue = gcnew vueHTML;
    		MaVue->SetBounds(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
    		MaVue->Activate();
    		MaVue->Show();
    		MaVue->BringToFront();
    		MaVue->visionneuse->Navigate(gcnew Uri(gcnew String(tpFic)));
    		break;
    	case -1:
    		MaVue->Close();
    	}
    }
    #pragma unmanaged

    L'appel avec "code = 1" fonctionne et j'ai bien mon HTML visible.
    Très logiquement l'appel avec "code = 2" est impossible puisque la référence 'MaVue' n'existe plus !

    En bon programmeur à l'ancienne l'idée serait de créer une variable globale avec la référence ... cela est interdit ! "Pourquoi faire simple quand on peut faire compliqué" est manifestement l'adage préférés des concepteurs anglo-saxons.

    Pourtant, si la référence n'existe plus l'objet lui est là !
    Comment récupérer un moyen d'agir sui lui ? Ne serais-ce que pour faire "MaVue->Close()" à la sortie de la boite de dialogue.

    Je suppose qu'il y a un moyen, sans doute évident (!) ...
    Merci de votre aide.

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Bonjour,
    La méthode "à l'ancienne" peut marcher une fois qu'on connait le "truc" pour stocker un pointeur managé dans une classe/structure non-managée:

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #include <vcclr.h> //De mémoire c'est celui-ci qui définie gcroot
     
    class donneesFenetre
    {
    public://TODO: Encapsulate this better
    	gcroot<vueHTML^> maVue;
    };

    Et ensuite, la "bonne" méthode "à l'ancienne" qui, au lieu d'utiliser une var globale, utilise GetWindowLongPtr et SetWindowLongPtr:
    Code C++ : 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
     
    INT_PTR MaProcDialogue(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	donneesFenetre * pDonnees = reinterpret_cast<donneesFenetre *>(GetWindowLongPtr(hDlg, DWLP_USER));
    	INT_PTR ret = TRUE;
    	switch(msg)
    	{
    	case WM_INITDIALOG:
    		pDonnees = new donneesFenetre(); //Il faut utiliser new et pas un bête malloc ici, parce que gcroot<> n'est pas un type Plain Old Data (POD)
    		SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pDonnees);
    		break;
    	case WM_DESTROY:
    		delete pDonnees;
    		pDonnes = NULL;
    		SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pDonnees);
    		break;
    	...
     
    	default:
    		ret = FALSE;
    		break;
    	}
    	return ret;
    }
    Et en bonus, maintenant que tu as un pointeur associé à ta Dialog, tu peux aussi en faire une vraie classe dont tu appelles les fonctions membres depuis ta DialogProc. Très utile.
    Code C++ : 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
    31
    32
    33
    class donneesFenetre
    {
    private:
    	gcroot<vueHTML^> maVue;
    	INT_PTR ProcDialogue(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
    public:
    	static INT_PTR MaProcDialogue(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
    };
     
    INT_PTR donneesFenetre::MaProcDialogue(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	donneesFenetre * pDonnees = reinterpret_cast<donneesFenetre *>(GetWindowLongPtr(hDlg, DWLP_USER));
    	INT_PTR ret = TRUE;
     
    	if(msg == WM_INITDIALOG)
    	{
    		pDonnees = new donneesFenetre(); //Il faut utiliser new et pas un bête malloc ici, parce que gcroot<> n'est pas un type Plain Old Data (POD)
    		SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pDonnees);
    	}
     
    	if(pDonnees != NULL)
    		ret = pDonnees->ProcDialogue(hDle, msg, wParam, lParam);
    	else
    		ret = FALSE;
     
    	if(msg == WM_DESTROY)
    	{
    		delete pDonnees;
    		pDonnes = NULL;
    		SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pDonnees);
    	}
    	return ret;
    }
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

Discussions similaires

  1. Réponses: 12
    Dernier message: 30/01/2006, 21h13
  2. [C++] Appel via paramètres non managés
    Par JulienDuSud dans le forum Framework .NET
    Réponses: 4
    Dernier message: 28/12/2005, 10h42
  3. code non managé avec interface managée ...
    Par izbad dans le forum MFC
    Réponses: 6
    Dernier message: 19/12/2005, 16h36
  4. Ingres 2.6 et .Net (managé ou non)
    Par moimoi dans le forum Autres SGBD
    Réponses: 2
    Dernier message: 08/03/2004, 08h58

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