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 :

Une application MDI dans une Dll..


Sujet :

MFC

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    72
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Mai 2007
    Messages : 72
    Par défaut Une application MDI dans une Dll..
    Bonjour à toutes et à tous !


    Voilà ça fait deux jours que je lis la doc et que je brasse des tonnes d'exemples donc je me dis que enfin je dois avoir le droit de poser la question. C'est une question que j'ai vu posée pas mal de fois mais les réponses n'ont pas été d'une grande aide.

    Donc mon projet repose sur le développement d'une application. Comme je l'ai écrit dans le sujet, il s'agit d'une Dll qui sera chargée depuis un éxécutable quelconque. Je veux que la Dll charge une application MFC de type MDI.

    ce que je fais pour l'instant :

    1. CMyApp * theApp ; // dérivée de CWinApp of course, objet global

    2. le point d'entrée (extern C etc.) de la Dll fait :
    theApp = new CMyApp() ;
    theApp->InitInstance() ;

    je suis passé par une fonction externe et un pointeur parceque quand je déclarais theApp en tant que CMyApp et que je loadais la Dll, ça allait bien dans la constructeur mais pas dans InitInstance().

    Cela étant dit, même si j'y arrive, je ne m'en sors pas.. le debug me sors toujours un plantage sur telle ou telle assertion :

    ASSERT(afxCurrentInstanceHandle != NULL);

    ou encore :

    ASSERT(afxCurrentInstanceHandle == m_hInstance);


    j'ai essayé les trucs les plus souvent recommandés :

    AFX_MANAGE_STATE(AfxGetStaticModuleState());
    au tout début de ma fonction externe (le point d'entrée de la Dll)

    AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)
    histoire de voir si ça marcherait pas au cas où..

    ou encore :

    AfxRegisterWndClass(..)



    Donc voilà en gros j'arrive pas à lancer une appli MDI à partir d'une DLL, sachant que l'éxécutable qui la chargera ne devra rien avoir à voir là dedans.
    Bon et bien j'espère que quelqu'un va sourire et se dire "mon dieu le problème est bien connu" et me donner la réponse, parceque là je stagne


    désolé si je ne suis pas très clair, je suis conscient d'avoir le nez dans mon programme, n'hésitez pas à me demander des explications


    A bientôt !



    totem, qui croise les doigts

  2. #2
    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
    salut,
    non ce n'est pas tres clair...
    pour moi c'est le programme qui charge la DLL et non l'inverse..
    comment est elle chargée ?
    c'est une dll d'extensions ?

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    72
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Mai 2007
    Messages : 72
    Par défaut
    En fait je voudrais faire une application MDI qui soit toute intégrée dans une dll, et quand je charge la dll à partir d'un autre programme, paf ! ça lance l'application.

    mais il me semble qu'il y a comme un problème de "pompe de messages" ou quelque chose dans ce genre là (je débute en MFC)

  4. #4
    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
    pour que ça fonctionne (en premier lieu) il faut que ta dll soit une dll d'extension MFC...

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    72
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Mai 2007
    Messages : 72
    Par défaut
    Ok.. merci pour l'info


    donc si je lis dans la doc :

    1. Seuls les exécutables MFC (applications ou DLL normales) qui sont générés à l'aide de la version partagée des MFC peuvent utiliser une DLL d'extension

    et

    2. Les DLL d'extension ne doivent pas instancier une classe dérivée de CWinApp, mais doivent se fier à l'application cliente (ou DLL) pour la fourniture de cet objet. (tiens d'ailleurs tu me dis qu'il faut que ce soit une dll d'extension mais là ils disent qu'il ne faut pas d'objet dérivé de CWinApp)

    ça veut dire que je ne peux pas faire une application MDI encapsulée dans une dll et seulement dedans (comportement inclus)

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Je n'en suis pas certain.
    Tu peux peut-être essayer une DLL MFC régulière, dont une fonction ferait le tout (mais j'ignore ce qui doit se passer au niveau de sa CWinApp, je n'ai jamais fait de DLL MFC régulière.

    Ou bien, tu peux aussi faire du MDI sans MFC, mais tu n'auras plus le modèle Document/Vue...
    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.

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    72
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Mai 2007
    Messages : 72
    Par défaut
    A propos des regular DLL :

    Note that the CWinApp::Run mechanism does not apply to a DLL, because the application owns the main message pump. If your DLL brings up modeless dialogs or has a main frame window of its own, your application's main message pump must call a DLL-exported routine that calls CWinApp:reTranslateMessage.

    Or je ne veut rien avoir à faire dans l'application appelante.
    Donc je pense que je vais réorienter la conception de mon projet, soit en ne faisant pas une appli MDI mais plutôt une floppée de CDialog-derived , soit en faisant un éxécutable MDI.


    Merci pour ces réponses rapides, je préssentais bien que je me plantait en continuant dans cette voie.
    Bonne journée à tous, n'hésitez pas à continuer la conversation si vous avez des idées


    totem, qui re-re-repart de 0.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Il y a la théorie, et la pratique.
    Si l'application appelante n'a pas de pompe à message, tu peux mettre celle-ci dans une fonction de la DLL...

    Hors MFC, USER32.DLL ne se gène pas avec MessageBox() et DialogBoxParam()...
    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.

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    72
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Mai 2007
    Messages : 72
    Par défaut
    je vois !

    alors pendant que j'y suis tu connais un bon lien ou une piste (genre nom de classe, etc.) pour que je voie un peu la tête d'une pompe à message faite maison ?
    Parceque je ne cacherai pas que j'ai déjà essayé ce subterfuge, mais le seul exemple que j'ai trouvé utilisait des librairies ATL inconnues.

    j'abuse peut etre, mais ça complèterai bien le sujet.. non ?

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    La pompe à message la plus simple, c'est ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    MSG msg;
    while(GetMessage(&msg, NULL, 0, 0)>0)
    {
        DispatchMessage(&msg);
    }
    Ensuite, plusieurs choses peuvent compliquer la pompe à message (TranslateMessage(), TranslateAccelerator(), CWinApp::PreTranslateMessage(), etc.).
    Tu peux regarder le code source de CWinApp::Run() pour te faire une idée de ce que doit faire une pompe à messages MFC...
    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.

  11. #11
    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

  12. #12
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    72
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Mai 2007
    Messages : 72
    Par défaut
    Et bien si ça marche, je vous tire mon chapeau bien bas et je posterai le code de la solution
    En tout cas merci pour les réponses, c'est très appréciable

  13. #13
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    72
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Mai 2007
    Messages : 72
    Par défaut
    hmmm, je pense je ne suis pas loin en effet, mais il me reste toujours ce problème de ASSERT(afxCurrentInstanceHandle == m_hInstance) qui fait sauter l'appli en debug (comme en release d'ailleurs) à la fonction void CWinApp::AssertValid() const

    Et le debug dit que justement, m_hInstance est unused = CXX0030: Error: expression cannot be evaluated alors que m_pszAppName est bien setté au nom de mon application.
    Je dois m'emmêler les pinceaux quelque part

  14. #14
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    72
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Mai 2007
    Messages : 72
    Par défaut
    Voilà j'ai un truc qui tourne, donc j'en mets le squelette ci-dessous :

    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
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
     
     
    CMyApp theApp;			// The one and only one application object
     
     
    BOOL CMyApp::OnIdle(LONG lCount){
     
    	CWinApp::OnIdle(lCount) ;
    	return(FALSE);
    }
     
    BOOL CMyApp::PreTranslateMessage(MSG* pMsg){
     
    	return CWinApp::PreTranslateMessage(pMsg) ;
    }
     
    void RunMessagePump() 
    { 
    	AFX_MANAGE_STATE(AfxGetStaticModuleState());
       // Handle dialog messages 
        MSG msg;
    	BOOL bRet ;
     
    	// GetMessage() returns :
    	// 1..n	if there is a message
    	// 0	if the message is WM_QUIT (end of application)
    	// -1	if there is an error
    	//****************************************************
        while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0 ) 
        {
    		if (bRet == -1){
     
    			fprintf(stderr, "Error while receiving messages : %u\n", GetLastError() ) ;
    			break ;
     
    		}else{
     
    			//fprintf(stderr, "Message = %u \n", msg.message ) ;
     
    			if (!theApp.PreTranslateMessage(&msg)){
     
    				//fprintf(stderr, "theApp a pretranslate le message\n" ) ;
    				::TranslateMessage(&msg); 
    				::DispatchMessage(&msg); 
    			}            
    			theApp.OnIdle(0);   // updates user interface 
    			theApp.OnIdle(1);   // frees temporary objects
    		}
        }
    	fprintf(stderr, "exiting message pump\n" ) ;
    	theApp.ExitInstance() ;
    }
     
    /********************************************************************
    *                       extern "C" BOOL __declspec(dllexport) Start()
    *       
    *                       the entry point of the DLL.
    *                       'Start' is the function that is called by the external executable.
    *                       It initialize a MyApp object and by this mean
    *                       lauch a instance of the program.
    *********************************************************************/
     
    extern "C" BOOL __declspec(dllexport) Start()
    {
     
    	AFX_MANAGE_STATE(AfxGetStaticModuleState());	// for handles safety
     
    	RunMessagePump() ;						// simulate a main message loop
     
    	return FALSE;
    }
     
     
    /********************************************************************
    *                       MyApp
    *       
    *                       This class declares, initializes and manage the
    *                       application through a MDI architecture
    *********************************************************************/
    CMyApp::CMyApp()
    : CWinApp( "Target Builder" )
    {
    	fprintf(stderr, "Constructeur MyApp()..\n") ;
     
    	/* init ptr members here */
    }
     
     
    /********************************************************************
    *       BOOL    InitInstance()
    *       
    *                       CWinApp overriden method
    *                       Used as the application entry point
    *********************************************************************/
    BOOL CMyApp::InitInstance(){
     
    	if( !CWinApp::InitInstance() )
    		return FALSE ;
     
    	/* init your instance here */
     
    	return TRUE;
     
    }

    Attention : cet exemple n'est pas bétonné. seulement ça tourne donc ça donne une idée de comment on peut faire..

    Merci encore pour vos réponse, je l'ai mon appli en Dll !!

Discussions similaires

  1. Réponses: 5
    Dernier message: 31/07/2007, 16h34
  2. Réponses: 2
    Dernier message: 15/10/2006, 18h01
  3. Comment fermer une fenêtre Child dans une application MDI
    Par bahiatoon dans le forum C++Builder
    Réponses: 9
    Dernier message: 05/10/2006, 08h57
  4. Réponses: 3
    Dernier message: 08/07/2006, 19h59
  5. Réponses: 11
    Dernier message: 06/12/2005, 08h23

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