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 :

DialogBox non-Modal MFC DLL ne repond pas


Sujet :

MFC

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 91
    Points : 27
    Points
    27
    Par défaut DialogBox non-Modal MFC DLL ne repond pas
    Bonsoir,

    j'ai une application non MFC, avec un simple main, qui appelle une fonction d'une DLL MFC que j'ai creee.
    Cette DLL fait ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    void mafn()
    {
    CMyDialog* dlg = new CMyDialog();
    dlg->Create(IDD_DIALOG1,0);
    dlg->ShowWindow(SW_SHOW);
    dlg->UpdateWindow();
    }
    Le probleme est que ma fenet re s'affiche mais elle ne repond a rien. Il y a le sablier windows quand je met la souris dessus.
    Mon but est de remplir une treeviewdans ce dialog, avec une fonction mafonction2().
    Que dois-je faire svp sachant que mon application de test ne doit en aucun cas etre MFC.
    Je voudrais que quand je debuggue, arrivé a un breakpoint, voir mon dialog, et voir les donnees que j'ajoute dans le treeView, p.exemple je rajoute toto, je veux le voir, puis je continue en debug pas a pas, j'ajoute titi et je veux voir toto et titi.

    Merci

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 058
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 058
    Points : 12 093
    Points
    12 093
    Par défaut
    Pourquoi votre application de test ne doit en aucun cas être MFC ?

    Pour pouvoir utiliser correctement un dll MFC, il faut que l'exécutable soit MFC.

  3. #3
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Bonjour et bienvenu,
    A priori, je dirais qu'il n'y a pas de boucle de message. C'est pourquoi la fenêtre reste figée.
    Si vraiment tu ne veux pas de MFC dans ton application principale, la seule solution que je vois, c'est de créer un thread IHM (avec une boucle de message) dans ta DLL et de lancer la boîte de dialogue dans ce thread. En revanche, il faudra faire attention ensuite à synchroniser les données échangées.

  4. #4
    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
    Bonjour,

    Principe:
    Une DLL qui se veut être MFC qui veut être utilisée par une application (exe) non MFC doit être une DLL régulière MFC.
    Et donc chaque méthode exportable par cette DLL doit avoir le corps suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    extern "C" void WINAPI AfxMyDllMethod()
    {
             AFX_MANAGE_STATE(AfxGetStaticModuleState());  // redéfinit les paramètres globaux dans les MFC.
     
             //...
    }

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 91
    Points : 27
    Points
    27
    Par défaut
    la n'est pas le probleme, en creant la fenetre dans un autre thread avec boucle de message, la fenetre ne freeze plus, mais je n'arrive pas a ajouter des elements dans le CTreeCtrl en dehors du thread ou j'ai ma boucle de message.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dlg->m_tree.InsertItem(L"toto");
    crashe car m_hwnd = 0

    J'ai essayé GetActiveWindow()->GetSafeHwnd(), ca retourne NULL en dehors du thread.
    J'ai donc memorisé Hwnd depuis le thread creant la fenetre, puis fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    dlg->m_tree.Attach(hwnd);
    dlg->m_tree.InsertItem(L"toto");
    ne crashe plus mais ca n'affiche rien

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 058
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 058
    Points : 12 093
    Points
    12 093
    Par défaut
    Vous êtes en train de jouer avec le feu (ou avec Mike Tyson).
    En n'ayant pas un exécutable MFC:
    - Vous avez des problèmes avec les fenêtres créées car le hook sur la création de fenêtre n'a pas été installé avant la création de toutes les fenêtres.
    - Les variables statiques de la lib MFC risquent d'être mal initialisées
    - des threads ne sont pas MFC-aware
    - etc.

    Vous allez vous faire boxer la figure avant de pouvoir faire quelque chose d'utile.

    Pourquoi avoir un exécutable non-MFC ?

  7. #7
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 352
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 352
    Points : 20 359
    Points
    20 359
    Par défaut
    Citation Envoyé par kaiser92 Voir le message
    Bonsoir,

    j'ai une application non MFC, avec un simple main, qui appelle une fonction d'une DLL MFC que j'ai creee.
    Si c'est une appli console avec un simple void main() c'est certain que cela ne risque pas de marcher !
    une application console n'a pas de HWND !
    Si tu as jeté un coup d'oeil au MSDN ( j'espère que tu l'as à portée de main au moins), tu verras qu'en appelant CDialog::Create en passant NULL comme CWnd prend le HWND du thread parent.

    You can put the call to Create inside the constructor or call it after the constructor is invoked.

    Two forms of the Create member function are provided for access to the dialog-box template resource by either template name or template ID number (for example, IDD_DIALOG1).

    For either form, pass a pointer to the parent window object. If pParentWnd is NULL, the dialog box will be created with its parent or owner window set to the main application window.

    The Create member function returns immediately after it creates the dialog box.

  8. #8
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 352
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 352
    Points : 20 359
    Points
    20 359
    Par défaut
    Citation Envoyé par bacelar Voir le message
    En n'ayant pas un exécutable MFC:
    - Vous avez des problèmes avec les fenêtres créées car le hook sur la création de fenêtre n'a pas été installé avant la création de toutes les fenêtres.
    Qu'est ce qu'un hook vient faire ici ?
    - Les variables statiques de la lib MFC risquent d'être mal initialisées
    - des threads ne sont pas MFC-aware
    Quel est le rapport je n'arrive vraiment pas à comprendre !
    On peut très bien faire une appli win32 en n'importe quel langage informatique pour plateforme win32 et appeler une dll qui comporte des MFC.
    Et lycée de Versailles également

  9. #9
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 058
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 058
    Points : 12 093
    Points
    12 093
    Par défaut
    Citation Envoyé par Mat.M Voir le message
    Qu'est ce qu'un hook vient faire ici ?
    Les MFC, du moins l'implémentation 4.2, utilise en hook sur la création de fenêtres pour permettre de garder la relation entre l'objet CWin et le handler de fenêtre et aussi pour les sous-classer et donc pour avoir un comportement compatible avec le runtime MFC.

    Citation Envoyé par Mat.M Voir le message
    Quel est le rapport je n'arrive vraiment pas à comprendre !
    Regardez du coté de l'implémentation d'AfxBeginThread (http://msdn.microsoft.com/en-us/libr...8e(VS.80).aspx), vous verrez de quoi je parle par variables statiques et thread MFC-aware.
    Citation Envoyé par Mat.M Voir le message
    On peut très bien faire une appli win32 en n'importe quel langage informatique pour plateforme win32 et appeler une dll qui comporte des MFC.
    Et lycée de Versailles également
    Bin non. cf réponse de Gabrielly

  10. #10
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par kaiser92 Voir le message
    la n'est pas le probleme, en creant la fenetre dans un autre thread avec boucle de message, la fenetre ne freeze plus, mais je n'arrive pas a ajouter des elements dans le CTreeCtrl en dehors du thread ou j'ai ma boucle de message.
    Les objets MFC ne se partagent pas bien entre thread. Ils ne sont pas fait pour. Il faut échanger les HWND vers les threads qui n'ont pas créé la fenêtre.

  11. #11
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 352
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 352
    Points : 20 359
    Points
    20 359
    Par défaut
    Je partage la solution de 3d Archi ; sans "winproc" c.a.d. boucle de message rattachée à la fenêtre cela ne risque pas de marcher

    Citation Envoyé par bacelar Voir le message
    Bin non. cf réponse de Gabrielly
    mais justement si : A condition comme il dit "d'exporter" des méthodes comme dans une dll "classique" comme le dit si bien Gabrielly

  12. #12
    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
    Il y a un peu d'embrouille.

    1. Tu cherches à utiliser une Dll MFC dans un exe non MFC.
    2. Tu crées un autre thread et tu utilises des objets MFC entre les threads.

    D'abord pour ta DLL commence par respecter le premier principe car ta "void mafn()" n'est pas correctement exportable. Quelle est la nature de ta DLL MFC? Je te conseille une liaison dynamique avec celle des MFC (version MFC shared)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    extern "C" void WINAPI mafn()
    {
          AFX_MANAGE_STATE(AfxGetStaticModuleState());
     
          CMyDialog* dlg = new CMyDialog();
          dlg->Create(IDD_DIALOG1,0);
          dlg->ShowWindow(SW_SHOW);
          dlg->UpdateWindow();
    }
    Ensuite voici un deuxième principe :
    Le thread qui crée des objets MFC en particulier des CWnd-Derived Object est responsable de leur destructions et de leur disponibilités dans le Map des HWND. En d'autres termes de leur durée de vie.
    Il n'est pas bon pour un utilisateur moins expérimenté de partager des objets MFC entre les threads.

    Mais toutefois les objets MFC peuvent passer d'un thread à autre. Tu peux communiquer entre les threads en utilisant soit des objects de synchronisations ou des messages windows que tu définits.

    Si je veux intéragir avec un CWnd-Derived Object crée par un autre thread par exemple faire des InsertItem() ou faire évoluer une barre de progression. Tu ne peux pas appelé ces méthodes directement dans le thread qui n'est pas le OWNER mais tu dois poster un User Message au OWNER de le faire lui-même.

    Exemple :
    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
     
    UINT AfxAnotherThreadProc(LPVOID lpParam)
    {
            CMyDialog* pDlg = (CMyDialog*) lpParam;
     
    //...
            for(int i = 0; i < nCount; i++)
            {
                   static CString strItemText;
                   strItemText = "Toto";
                   WPARAM wp = i;
                   LPARAM lp = (LPARAM) (LPCTSTR) strItemText;
                   pDlg->SendMessage(WM_INSERT_ITEM_IN_MAIN_THREAD, wp, lp);  // le tread principale se charge de faire l'insertion
            }
     
    //...
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    LPRESULT CMyDialog::OnInsertItemInMainThread(WPARAM wParam, LPARAM lParam)
    {
           int i = (int) wParam;
           CString strItemText = (LPCTSTR) lParam;
           m_Tree.InsertItem(strItemText);
           //...

Discussions similaires

  1. Fenêtre non modale à patir d'une DLL
    Par Chachane dans le forum MFC
    Réponses: 2
    Dernier message: 07/02/2010, 18h34
  2. [MFC] CPropertySheet non modale
    Par Philippe320 dans le forum MFC
    Réponses: 4
    Dernier message: 02/01/2007, 18h39
  3. [MFC] Créer une CDialog non modale dans un thread
    Par fleur_de_rose dans le forum MFC
    Réponses: 3
    Dernier message: 29/09/2006, 12h43
  4. Réponses: 6
    Dernier message: 27/07/2005, 15h49
  5. [MFC] instance unique de dialogue non modale
    Par venomelektro dans le forum MFC
    Réponses: 5
    Dernier message: 02/02/2005, 13h41

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