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 :

Cause d'un plantage de DoModal ?


Sujet :

MFC

  1. #1
    Membre confirmé
    Inscrit en
    Janvier 2005
    Messages
    76
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Janvier 2005
    Messages : 76
    Par défaut Cause d'un plantage de DoModal ?
    Bonjour,

    Quelles peuvent être les causes d'un plantage d'une application entière sur une instruction DoModal ?

    Petites explications :
    - Une CFormView créé une CDialog (dlg1) avec un bouton (btn1).
    - Lors de l'appui sur btn1, je lance une autre CDialog (dlg2) avec un bouton OK.
    - La CDialog dlg2 doit être Modal, le temps que l'utilisateur n'appuie pas sur OK.

    Plantage :
    - Quand l'utilisateur appuie sur le OK de dlg2 ... l'application plante :'(

    Merci pour votre aide

  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,
    les causes peuvent être multiples....
    tu as lancé ton application en mode trace/debug ?
    quand ça plante remonte la pile des appels jusqu'à ton code .
    ou indique nous le message d'assertion d'erreur et éventuellement la ligne qui provoque l'erreur.

  3. #3
    Membre émérite
    Avatar de Spout
    Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    904
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Février 2007
    Messages : 904
    Par défaut
    J'ajoute qu'il serait également utile de nous donner au moins le code qui gère le clic sur le bouton OK de la 2e CDialog.

  4. #4
    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
    Par défaut
    Sans plus d'info, ca va être très dur. Les pistes en aveugle peuvent être:
    -> Regarder du côté de la gestion du CDialog2::OnOk(),
    -> Regarder du côte du destructeur de CDialog2.
    Mais comme dit précédemment rien ne garanti que ton problème soit à ce niveau.
    Enfin, quand ça plante, la première démarche.... c'est de debugger pour comprendre. Comprendre permet d'apprendre et de ne pas poser de questions trop vagues.

  5. #5
    Membre confirmé
    Inscrit en
    Janvier 2005
    Messages
    76
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Janvier 2005
    Messages : 76
    Par défaut
    Il est vrai que je suis resté vague ... un peu volontairement d'ailleurs.

    Pour vous répondre :
    - J'ai exécuter en mode Debug avec point des points d'arrêt sur ma CDialog2 (En particulier le DoDataExchange, OnInitDialog, OnOK et PostNcDestroy comme indiquer dans d'autres sujets sur ce forum) --> Verdict : Plantage après le OnOK et avant le PostNcDestroy ... donc pendant un DoDataExchange, à ce moment là, l'affichage disparait mais le code est toujours exécuter pendant quelques instants, jusqu'a une mise à jour de l'affichage : D'un contrôle ou de la fenêtre ... Ensuite c'est figé.

    - Donc il semblerait que celà viennent des contrôles placés sur la CDialog2, pourtant aucunes Assertion, aucun message d'erreur (même dans la fenêtre Debug)

    - j'ai alors songé à un ID de ressource qui aurait disparu ... fausse piste apparament.

    Le code en question :
    Appel de la CDialog2
    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
     
    void CDialog1::CalculerResultat()
    {
    	// Calcul du résultat
    	// ...	
     
    	// Affichage du résultat
    	// CDialog2 * pDlg2 = new CDialog;
    	CDialog2 dlg2;	
    	/*pDlg2->Create(CDialog::IDD, this);
    	pDlg2->ShowWindow(SW_SHOW);
    	*/
    	int nRes = dlg2.DoModal();
    	if ( nRes == IDOK)
    	{
    		return;
    	}
    }
    La CDialog2 :
    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
     
    CDialog2::CDialog2(CWnd* pParent /*=NULL*/)
    	: CTplDlgColor<CDialog>(CDialog2::IDD, pParent)
    {
    	//{{AFX_DATA_INIT(CDialog2)
    	m_strAxeS = _T("");
    	m_strAxeL = _T("");
    	m_strAxeU = _T("");
    	m_strAxeR = _T("");
    	m_strAxeB = _T("");
    	m_strAxeT = _T("");
    	//}}AFX_DATA_INIT
    }
     
     
    void CDialog2::DoDataExchange(CDataExchange* pDX)
    {
    	CTplDlgColor<CDialog>::DoDataExchange(pDX);
    	//{{AFX_DATA_MAP(CDialog2)
    	DDX_Text(pDX, IDC_EDIT_AXE_S, m_strAxeS);
    	DDX_Text(pDX, IDC_EDIT_AXE_L, m_strAxeL);
    	DDX_Text(pDX, IDC_EDIT_AXE_U, m_strAxeU);
    	DDX_Text(pDX, IDC_EDIT_AXE_R, m_strAxeR);
    	DDX_Text(pDX, IDC_EDIT_AXE_B, m_strAxeB);
    	DDX_Text(pDX, IDC_EDIT_AXE_T, m_strAxeT);
    	//}}AFX_DATA_MAP
    }
     
    BOOL CDialog2::OnInitDialog() 
    {
    	CTplDlgColor<CDialog>::OnInitDialog();
     
    	SetDialogBkColor(/*RGB(193, 193, 255)*/RGB(51,102,153), RGB(255, 255, 255));
     
    	UpdateData(FALSE);	
     
    	return TRUE;  // return TRUE unless you set the focus to a control
    	              // EXCEPTION: OCX Property Pages should return FALSE
    }
     
    void CDialog2::OnOK() 
    {
    	CTplDlgColor<CDialog>::OnOK();
    }
     
    void CDialog2::PostNcDestroy() 
    {
    	CTplDlgColor<CDialog>::PostNcDestroy();
    	delete this;
    }
    J'ai 6 CEdit sur la CDialog2, je les ai mis en CString via le ClassWizard (d'ou le UpdateData(FALSE) du OnInitDialog.
    Le template CTplDlgColor est celui de farscape pour la classe XtabCtrl.

    J'espère avoir répondu a toutes vos attentes ...

  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
    salut,
    pourquoi avoir un delete de this si la boite de dialogue est modale ?
    plantage assuré puisque l'objet est dans la pile ...

  7. #7
    Membre confirmé
    Inscrit en
    Janvier 2005
    Messages
    76
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Janvier 2005
    Messages : 76
    Par défaut
    En effet petit oubli de mon code actuel ...
    J'ai tellement testé avec Modal et non-modal que le delete this est resté ... Oups.

    Bon je l'ai commenté, toujours un plantage au meme endroit.
    j'ai supprimé la fonction virtuelle PostNcDestroy ... idem, plantage.

  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
    on peut avoir le code responsable de l'erreur ?

  9. #9
    Membre confirmé
    Inscrit en
    Janvier 2005
    Messages
    76
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Janvier 2005
    Messages : 76
    Par défaut
    En fait je ne vois aucune erreur ... pas d'assertion, aucun message sur l'écran Debug, l'appli est toujours lancée, mais plus afficher ... et figer aussi.

    Et ça se produit quand j'ai appuyé sur le Bouton OK, et que le code passe (pour la 3ème fois dans le DoDataExchange).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void CDialog2::DoDataExchange(CDataExchange* pDX)
    {
    	CTplDlgColor<CDialog>::DoDataExchange(pDX);
    	//{{AFX_DATA_MAP(CDialog2)
    	DDX_Text(pDX, IDC_EDIT_AXE_S, m_strAxeS);
    	DDX_Text(pDX, IDC_EDIT_AXE_L, m_strAxeL);
    	DDX_Text(pDX, IDC_EDIT_AXE_U, m_strAxeU);
    	DDX_Text(pDX, IDC_EDIT_AXE_R, m_strAxeR);
    	DDX_Text(pDX, IDC_EDIT_AXE_B, m_strAxeB);
    	DDX_Text(pDX, IDC_EDIT_AXE_T, m_strAxeT);
    	//}}AFX_DATA_MAP
    }

  10. #10
    Membre confirmé
    Inscrit en
    Janvier 2005
    Messages
    76
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Janvier 2005
    Messages : 76
    Par défaut
    J'ai testé cette CDialog dans un autre contexte ... appui sur un bouton --> création de la CDialog2 ... et ça marche très bien en modal ou non-modal ...

    Le problème pourrait donc venir de mon appel ... Est ce qu'un Thread exécuter en meme temps pourrait perturber la CDialog ?

  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
    Par défaut
    ça dépend si le thread touche à la dialogue...
    mais tel que je vois la chose ,il semblerait que ton thread monopolise le cpu...
    d'où l'impression d'être figé.

  12. #12
    Membre confirmé
    Inscrit en
    Janvier 2005
    Messages
    76
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Janvier 2005
    Messages : 76
    Par défaut
    Ok alors j'explique le thread :

    J'ai un Thread de travail, qui appelle une fonction d'affichage.
    Cette fonction d'affichage calcule un résultat graphique et lance la dialogue CDialog2 ...

    Donc on peut dire que c'est le Thread qui lance la CDialog2

  13. #13
    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
    si le thread n'est pas fermé avant la fermeture de la boite de dialogue.
    et que celui-ci continue d'envoyer des messages à la dialogue
    tu peux avoir un dead lock : une boucle qui tourne dans le vide et qui fige l'application.

  14. #14
    Membre confirmé
    Inscrit en
    Janvier 2005
    Messages
    76
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Janvier 2005
    Messages : 76
    Par défaut
    Dans le fonctionnement par étape :
    - Lancement du Thread de travail
    - Acquisition de données
    - Calcul du résultat
    - Affichage du résultat, Dialogue Modal pour bloquer le traitement
    - Enregistrement d'un fichier de sauvegarde
    - Fermeture du Thread

  15. #15
    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
    Citation Envoyé par farscape Voir le message
    si le thread n'est pas fermé avant la fermeture de la boite de dialogue.
    et que celui-ci continue d'envoyer des messages à la dialogue
    tu peux avoir un dead lock : une boucle qui tourne dans le vide et qui fige l'application.
    ton cylcle d'actions ne répond pas à mon interrogation ci-dessus...

  16. #16
    Membre confirmé
    Inscrit en
    Janvier 2005
    Messages
    76
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Janvier 2005
    Messages : 76
    Par défaut
    Euh je dois avouer que j'ai eu du mal à comprendre là ou tu voulais en venir ... pourtant ça parait simple ... passons.

    La Boite de dialogue n'affiche que le résultat, c'est à dire une seule fois dans toute l'application.
    Et cette mise à jour est faite avant le DoModal ... cf http://cpp.developpez.com/faq/vc/?pa...ControlForward Comme tu l'as si bien expliqué.

    La boite de dialogue est modal, donc mon Thread est censé etre en "pause" le temps que je n'ai pas appuyer sur OK ...
    Lorsque que j'appuie sur OK, le Thread reprend son exécution, enfin normalement ...

    Dès que j'ai appuyer sur OK, la Dialogue est fermée, et je n'affiche rien dessus à partir de là ... tout à été fait avant justement !

  17. #17
    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
    tu as lancé la dialogue dans un message initié par le thread ?
    tu as suivi cette consigne de la faq:
    Citation Envoyé par faq
    Notes: La fonction thread peut être définie dans une classe si elle est déclarée statique.
    Dans le cas d'utilisation conjointe avec des boîtes de dialogue modales, il est préférable de poster (PostMessage) le message plutôt que de l'envoyer (SendMessage), afin d'éviter un problème de réentrance avec la pompe à messages du thread principal.

  18. #18
    Membre confirmé
    Inscrit en
    Janvier 2005
    Messages
    76
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Janvier 2005
    Messages : 76
    Par défaut
    Je n'utilise ni l'une ni l'autre de ces 2 fonctions ...

    Je te met le code de mon Thread :
    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
     
     
    void CDialog1::LancerAcquisition()
    {
    	AfxBeginThread(ThreadAcquisition, this);
    }
     
    UINT CDialog1::ThreadAcquisition(LPVOID pvParam)
    {
    	CDialog1*pThis=reinterpret_cast< CDialog1*>( pvParam) ;
    	srand(GetTickCount());
     
    	HCURSOR hCursor = GetCursor();
    	SetCursor( AfxGetApp()->LoadStandardCursor(IDC_WAIT) );
     
    	// Traitement de l'acquisition
    	// ...
     
    	pThis->CalculerResultat();
     
    	// ...
     
    	SetCursor(hCursor);	
     
        return TRUE;
    }
     
    void CDialog1::CalculerResultat()
    {
    	// Calcul du résultat
    	// ...	
     
    	// Affichage du résultat
    	CDialog2 dlg2;	
    	dlg2.m_strAxeS = L"OK";
    	int nRes = dlg2.DoModal();
    	if ( nRes == IDOK)
    	{
    		return;
    	}
    }

  19. #19
    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
    hé bien c'est encore pire ....
    tu ne peux pas lancer une boite de dialogue dans un thread de travail...
    CalculerResultat() doit être appelée à travers un message privé initié par le thread comme expliqué ici : http://cpp.developpez.com/faq/vc/?pa...keWorkerThread

  20. #20
    Membre confirmé
    Inscrit en
    Janvier 2005
    Messages
    76
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Janvier 2005
    Messages : 76
    Par défaut
    Encore une autre partie de la FAQ que je n'avais pas lu ...
    J'ai défini un message privé comme expliqué ici : http://cpp.developpez.com/faq/vc/?pa...PrivateMessage

    Et hop ça fonctionne du premier coup !
    Génial !

    Merci encore Farscape

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Plantage applet java à cause d'un socket
    Par malag dans le forum Entrée/Sortie
    Réponses: 8
    Dernier message: 29/01/2007, 12h49
  2. [MFC] Plantage au deuxieme DoModal() avec TIMER
    Par ricky78 dans le forum MFC
    Réponses: 3
    Dernier message: 25/09/2006, 16h17
  3. [debutant] plantage a cause du cosntructoeur et destructeur
    Par Battosaiii dans le forum Débuter
    Réponses: 11
    Dernier message: 12/11/2005, 19h13
  4. plantage a cause de CString::Format
    Par e-teo dans le forum MFC
    Réponses: 2
    Dernier message: 18/10/2005, 18h02
  5. [Oracle 9.1] Plantage SQL+ à cause d'une requête
    Par ftrifiro dans le forum Oracle
    Réponses: 8
    Dernier message: 04/10/2005, 15h08

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