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

MFC Discussion :

[MFC] Dll modifiant splitter de l'application parent


Sujet :

MFC

  1. #1
    Membre éclairé
    Inscrit en
    Février 2006
    Messages
    256
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 256
    Par défaut [MFC] Dll modifiant splitter de l'application parent
    Bonjour,

    J'ai une appli MDI qui ouvre une fenêtre separée en 2 par un splitter ( avec le document sous-jacent qui va bien.... ).
    Dans cette appli, j'arrive à modifier à volonté le contenu du "pane" de droite du splitter avec les commandes "m_split.deleteView , m_split.createView et m_split.Recalclayout".

    Mais voulant limiter la taille de mon exécutable, je veux faire effectuer cette action par une Dll en lui passant en paramètre dans la fonction exportée ( que j'appelle depuis l'application de départ ) le pointeur sur ma CMDIChildWnd qui contient le splitter.

    Lorsque je "linke" mon appli et sa dll en "MFC Shared DLL", ça fonctionne comme prévu MAIS quand je les passe toutes les 2 en "MFC static Library", j'ai un plantage... => et voilà le problème du présent sujet...

    NB: Ma DLL Linkée en static library, j'ai le Warning suivant
    " warning LNK4089: all references to "SHELL32.dll" discarded by /OPT:REF "

    Est-ce que ça peut venir de là et si oui comment y remédier ?

  2. #2
    Membre chevronné Avatar de stephdim
    Profil pro
    Inscrit en
    Août 2007
    Messages
    462
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 462
    Par défaut
    salut,

    tu as bien choisi DLL d'extension MFC et non DLL normale ?

    sinon je ne crois pas que le warning à a voir quoi que ce soit avec le probleme.
    ça t'indique, que dans les options de linkage tu as spécifié shell32.lib (pas toi, mais les MFC par un #pragma comment() ) et que finalement tu n'utilises aucune des fonctions de cette librairie. du coup, le linker te dis qu'il optimise et ne fera pas de liaison avec shell32 ...


    @+

  3. #3
    Membre éclairé
    Inscrit en
    Février 2006
    Messages
    256
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 256
    Par défaut
    Salut,

    J'ai fait ( Visual C++ 6.0 ) "File/New/Win32 Dynamic Link Library/Empty Project" tout court sans passer par AppWizzard.

    Voici des infos supplémentaires:

    Code appelant la DLL:
    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
     
    void CMonApp::OnDllLancer()
    {
    	HMODULE hDll;
    	if(hDll=::LoadLibrary("UneDll.dll"))
    	{
    		if((FARPROC&)ptrFonc=::GetProcAddress(hDll,"ChangerVueDroite"))
    		{
    			ptrFonc(m_pMaFille); // m_pMaFille est un ptr sur fenêtre contenant le CSplitterWnd
    		}
    		else
    		{
    			::MessageBox(NULL,"Impossible de trouver la fonction...","Erreur",MB_ICONSTOP|MB_OK);
    		}
    		::FreeLibrary(hDll);
    	}
    	else
    	{
    		::MessageBox(NULL,"Dll introuvable...","Erreur",MB_ICONSTOP|MB_OK);
    	}
    }
    Code de la DLL:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    #include "VueConsoleWeb.h"
     
    extern "C" void __declspec(dllexport) ChangerVueDroite(CMaFille *pFille)
    {
    	pFille->m_split.DeleteView(0,1);
    	pFille->m_split.CreateView(0,1,RUNTIME_CLASS(CVueConsoleWeb),CSize(200,200),NULL);
    	pFille->m_split.RecalcLayout();
    }
    sachant que CVueConsoleWeb est une classe dérivant de CHtmlView et définie dans ma DLL.

    NB:

    Dans ma fonction exportée, si je fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    pFille->m_split.GetActivePane()->GetDC()->TextOut(5,5,"Texte");
    => Aucun problème.
    C'est au niveau du DeleteView/CreateView que ça coince...

  4. #4
    Membre chevronné Avatar de stephdim
    Profil pro
    Inscrit en
    Août 2007
    Messages
    462
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 462
    Par défaut
    je te conseille quand meme de recréer proprement ton projet en choisissant DLL d'extension MFC par le wizzard

    ou sinon de rajouter le fichier dllmain.cpp

    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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
     
    // dllmain.cpp : Defines the initialization routines for the DLL.
    //
     
    #include "stdafx.h"
    #include <afxwin.h>
    #include <afxdllx.h>
     
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif
     
    static AFX_EXTENSION_MODULE MyExtDLL = { NULL, NULL };
     
    extern "C" int APIENTRY
    DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
    {
    	// Remove this if you use lpReserved
    	UNREFERENCED_PARAMETER(lpReserved);
     
    	if (dwReason == DLL_PROCESS_ATTACH)
    	{
    		TRACE0("MyExt.DLL Initializing!\n");
     
    		// Extension DLL one-time initialization
    		if (!AfxInitExtensionModule(MyExtDLL, hInstance))
    			return 0;
     
    		// Insert this DLL into the resource chain
    		// NOTE: If this Extension DLL is being implicitly linked to by
    		//  an MFC Regular DLL (such as an ActiveX Control)
    		//  instead of an MFC application, then you will want to
    		//  remove this line from DllMain and put it in a separate
    		//  function exported from this Extension DLL.  The Regular DLL
    		//  that uses this Extension DLL should then explicitly call that
    		//  function to initialize this Extension DLL.  Otherwise,
    		//  the CDynLinkLibrary object will not be attached to the
    		//  Regular DLL's resource chain, and serious problems will
    		//  result.
     
    		new CDynLinkLibrary(MyExtDLL);
     
    	}
    	else if (dwReason == DLL_PROCESS_DETACH)
    	{
    		TRACE0("MyExt.DLL Terminating!\n");
     
    		// Terminate the library before destructors are called
    		AfxTermExtensionModule(MyExtDLL);
    	}
    	return 1;   // ok
    }
    de bien régler le point d'entrée de la DLL sur DllMain (dans config du Linker)

    et de définir le symbole _AFXEXT dans les options du préprocesseur (config Compiler)

    c'est ton CHtmlView qui ne doit pas aimer la façon dont est linker la DLL ...

    mais le mieux est de passer par le Wizzard, pour etre sur de ne rien oublier

    @+

    ou essaye ceci :

    http://msdn.microsoft.com/en-us/libr...h5(VS.80).aspx

    donc

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
    avant de créer et de détruire ta View, dans le même scope.

    @+

  5. #5
    Membre éclairé
    Inscrit en
    Février 2006
    Messages
    256
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 256
    Par défaut
    Salut,

    J'ai essayé ce que tu dis.
    J'ai tenté de créer cette DLL par tous les moyens dont on dispose sous VC++6.0 pour créer un projet "non-vide".
    Ca fonctionne jusqu'à ce que je passe l'appli et la DLL en static Library.

    NB: Dans les exemple de code que j'ai donné, il y "::FreeLibrary()" => Lorsque je le mets, j'ai un plantage ( en Shared DLL ), et lorsque je ne le mets pas, c'est Ok.

    AFX_MANAGE_STATE ne donne rien pas plus que AFX_EXT_CLASS devant ma classe CVueConsoleWeb.

    En revanche je n'ai pas de problème si je fais une classe dérivant d'une CView classique....

    Pour résumer, ca coince avec une classe dérivant de CHtmlView ( peut-être que je l'implémente mal ) et lors du passage de Shared à Static library.


  6. #6
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    une dll d'extension ne peut pas utiliser les MFC en static, c'est uniquement dll partagée.
    si je reviens sur la premier post , il y a une incohérence de dire je veux gagner de la place et je mets du code dans une DLL puis après de dire je transforme tout en static, les éléments générés seront forcemment plus gros.
    surtout qu'avec visual 6.0 tu es pratiquement sûr que tous les pc sont à jour pour les dll.

  7. #7
    Membre éclairé
    Inscrit en
    Février 2006
    Messages
    256
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 256
    Par défaut
    Salut,

    Le problème est que l'application à laquelle je veux rajouter cette DLL tourne en static et que je ne veux pas la mettre en Shared car lorsque je l'ai débogué ( débutant que j'étais à l'époque ), il y avait un bug que je n'arrivais pas à solutionner si ce n'est de l'avoir eu passé en Static. Donc mon appli restera en static car je n'ai pas le tps et la motivation de me relancer dans la mise au point.
    C'est pourquoi sur les tests que je suis en train de faire, je laisse l'application de tests en static et si je fais la DLL en Shared, ça plante aussi car j'ai l'impression que l'un en static et l'autre en Shared ne s'entendent pas.
    Voila pourquoi je veux donc les 2 en static...

    Si tu peux m'apporter des éléments sur la différence entre les modes ( sans m'apporter la réponse à mon problème sur un plateau )... je suis tout ouï

  8. #8
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    ben le problème c'est que tu as deux lib mfc et deux CRT ( c runtime-library) donc deux espaces d'allocation géré différemment.
    donc il y a danger à manipuler les objets de l'"un dans l'autre ne serait qu'a cause des allocations mémoires réalisées dans des espaces différents.
    je ne sais pas comment tu manipules les objets passés du programme à la dll , par pointeur ?

  9. #9
    Membre éclairé
    Inscrit en
    Février 2006
    Messages
    256
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 256
    Par défaut
    Salut,

    Oui, je passe comme argument à la fonction exportée de ma dll un pointeur sur la classe dérivée de CMDIChildWnd contenant le splitter ( en n'oubliant pas d'inclure le bon *.h dans le projet de ma DLL ).
    Les 2 points qui m'étonnent sont les suivants ( rappel donc: les 2 sont en static ).
    => Si à la place de ma classe CVueConsoleWeb, j'en fais une autre classe dérivée tout simplement de CView, ça marche...
    => Dans l'appli de test, si je libère la DLL par ::FreeLibrary() juste après l'appel de la fonction exportée, j'ai un plantage ( comme je le précisais à StephDim un peu plus haut ) que ce soit avec la classe CVueConsoleWeb ou la classe dérivée de CView...

    Ce qui m'étonne aussi, c'est qu'une DLL doit pouvoir être écrite dans un langage et être appelé par un prg écrit dans un autre langage, donc l'histoire du problème du au CRT, je ne comprends pas

  10. #10
    Membre éclairé
    Inscrit en
    Février 2006
    Messages
    256
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 256
    Par défaut
    Salut,

    Information supplémentaire de débogage:

    La partie qui pose vraiment problème est apparemment le CreateView concernant le splitter.
    Le message d'erreur du débogger pointe sur le fichier WinSplit.cpp dans la partie CSplitter::CreateView et indique un problème à la ligne ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ASSERT(pViewClass->IsDerivedFrom(CWnd)
    ..voulant dire que la classe CVueConsoleWeb ne dérive pas de Cwnd alors qu'elle dérive de CView qui dérive de CWnd.

    Et ce aussi bien en static qu'en Shared...

  11. #11
    Membre émérite
    Avatar de Gabrielly
    Inscrit en
    Juin 2004
    Messages
    722
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 722
    Par défaut
    Salut Denn's

    La solution à ton problème est de créer une DLL d'extension MFC avec le Wizard. Et de ce savoir ce que tu mets dans cette DLL.
    Ainsi tu n'exporte pas des fonctions mais des classes entières.

    Citation Envoyé par Denn's
    Mais voulant limiter la taille de mon exécutable, je veux faire effectuer cette action par une Dll en lui passant en paramètre dans la fonction exportée ( que j'appelle depuis l'application de départ ) le pointeur sur ma CMDIChildWnd qui contient le splitter.
    Ajoute une classe enfant de CMDIChildWnd dans ta DLL (avec le wizard stp). Définit le code de changement de vue dans une méthode de cette classe.
    En d'autres termes ta frame enfant dans ton exe ne te servira presque pas.

    Citation Envoyé par Denn's
    sachant que CVueConsoleWeb est une classe dérivant de CHtmlView et définie dans ma DLL
    C'est bien, ainsi ta vue et ta frame sont dans la DLL. Les noms de leurs classes doivent être précédés de AFX_EXT_CLASS pour leur exportation.

    Citation Envoyé par Denn's
    Lorsque je "linke" mon appli et sa dll en "MFC Shared DLL", ça fonctionne comme prévu MAIS quand je les passe toutes les 2 en "MFC static Library", j'ai un plantage... => et voilà le problème du présent sujet...
    La réponse de Farscape est suffisante :
    Citation Envoyé par Farscape
    une dll d'extension ne peut pas utiliser les MFC en static, c'est uniquement dll partagée.
    si je reviens sur la premier post , il y a une incohérence de dire je veux gagner de la place et je mets du code dans une DLL puis après de dire je transforme tout en static, les éléments générés seront forcemment plus gros.
    surtout qu'avec visual 6.0 tu es pratiquement sûr que tous les pc sont à jour pour les dll.
    Donc oublie la liaison en static, tu violes les principes.
    Et puis ne charge plus ta DLL de façon explicte par LoadLibrary() pour faire ensuite des GetProcAddress
    Etablit plutôt une liaison implicite ie.
    Avec la librairie générée de ta DLL tu ajoute ta *.lib ton les paramètres de ton exe MDI et tu inserts les includes nécessaires dans ton projet MDI.

  12. #12
    Membre éclairé
    Inscrit en
    Février 2006
    Messages
    256
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 256
    Par défaut
    Bonjour,

    Je l'ai expliqué + haut, je ne passerai pas mon projet initial en Shared car pas le temps et l'envie de le mettre au point ( l'avoir passé en static était pour moi un moyen "facile" de résoudre un bug que je n'arrivai pas à solutionner en shared ).

    Ayant quand même cherché ce week-end, j'ai pu me rendre compte que le problème venait de la classe CHtmlView uniquement puisque j'arrive à faire ce que je veux si je fais à la place une classe dérivé de CView ou de CFomview...

    De plus, avoir essayé de faire une DLL d'extension MFC comme cela m'a été dit à maintes reprises n'a pas solutionné le problème.

    Donc, spécialistes de la classe CHtmlView, je vous écoute....

  13. #13
    Membre chevronné Avatar de stephdim
    Profil pro
    Inscrit en
    Août 2007
    Messages
    462
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 462
    Par défaut
    ..voulant dire que la classe CVueConsoleWeb ne dérive pas de Cwnd alors qu'elle dérive de CView qui dérive de CWnd.
    il doit probablement y avoir 2 jeux différents de CRuntimeClass pour CWnd (entre autres) qui cohabite ... dû à 2 instances MFC qui tournent en parrallèle ...

    donc RUNTIME_CLASS(CWnd) de ton App != RUNTIME_CLASS(CWnd) de ta DLL

    les CRuntimeClass sont des variables statiques

    Je l'ai expliqué + haut, je ne passerai pas mon projet initial en Shared car pas le temps et l'envie de le mettre au point
    mais tu n'as pas le choix ...

    c'est tout en shared avec DLL d'extension ...

    @+

  14. #14
    Membre éclairé
    Inscrit en
    Février 2006
    Messages
    256
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 256
    Par défaut
    Si il y a 2 jeux différents de CRuntimeClass, pourquoi ça fonctionne avec CView et CFormView et pas CHtmlView ( le problème vient bien d'elle )

    Et d'essayer en DLL d'extension MFC, ca ne fonctionne pas non plus ( si si, j'ai essayé )...

  15. #15
    Membre chevronné Avatar de stephdim
    Profil pro
    Inscrit en
    Août 2007
    Messages
    462
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 462
    Par défaut
    ben ça ne fonctionne pas dès que tu fais un controle sur le type de classe

    par exemple, un ASSERT_KINDOF() ou la méthode IsKindOf() ....

    de toute évidence, ça pose déjà probleme avec les CRuntimeClass, alors je ne parle pas du reste, que tu ne vois pas encore ...

    ça fonctionne en DLL d'extention à condition que tu aies les MFC en DLL (en shared) et non en static. En shared pour l'application et la DLL. (sinon meme probleme)

    @+

Discussions similaires

  1. [XL-2007] VBA-MFC Modifier la plage d'application d'une mise en forme conditionnelle
    Par sl.info dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 08/11/2010, 23h51
  2. Utiliser les breakpoints application MFC -> DLL -> C#
    Par PePedu78 dans le forum Visual Studio
    Réponses: 1
    Dernier message: 13/04/2008, 02h39
  3. [MFC][DLL]Afficher une CDialog ?
    Par matazz dans le forum MFC
    Réponses: 13
    Dernier message: 13/04/2005, 13h47
  4. [MFC] Controler les splitter
    Par toune dans le forum MFC
    Réponses: 6
    Dernier message: 19/01/2005, 12h20
  5. Réponses: 5
    Dernier message: 02/08/2004, 17h11

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