2008-12-04 3 views
0

Comment détruire un pointeur sur l'objet CFindReplaceDialog correctement?MFC CFindReplaceDialog destruction

Par exemple, j'ai la classe:

class CjumpView : public CRichEditView 
{ 
    CFindReplceDialog *m_pFRDlg; 
    // ... 


    }; 
CjumpView::CjumpView() 
: m_pFRDlg(NULL) 
{ 

} 

CjumpView::~CjumpView() 
{ 
    if(m_pFRDlg != NULL) 
    { 
     m_pFRDlg->DestroyWindow(); 
     delete(m_pFRDlg); 
    } 
} 

void CjumpView::OnEditFind() 
{ 
    if(m_pFRDlg == NULL) 
    { 
     const bool fShowFind = true; 
     m_pFRDlg = new CFindReplaceDialog(); 
     m_pFRDlg->Create(fShowFind, m_sFind, NULL, NULL, this) 
    } 

} 



LRESULT CjumpView::OnFind(WPARAM, LPARAM lParam) 
{ 
    LPFINDREPLACE lpFindReplace = reinterpret_cast<LPFINDREPLACE>(lParam); 
    if(lpFindReplace->Flags & FR_DIALOGTERM) 
    { 
     m_pFRDlg->DestroyWindow(); 
      delete(m_pFRDlg); 
      m_pFRDlg = NULL; 
     return NULL; 
    } 
    lpFindReplace->Flags = 0; 
    return NULL; 
} 

Dans l'article d'aide Visual Studio CFindReplaceDialog il est dit que les objets de cette classe doivent être créés en tas en utilisant l'opérateur « nouveau ». Ensuite, la fonction Créer un membre doit être appelée. Ma fonction "OnFind" réagit à la fermeture de ce dialogue de recherche. Il appelle la fonction DestroyWindow(), l'objet tente de supprimer la boîte de dialogue. Mais quand j'essaye d'appeler DestoyWindow() dans OnFind() ou dans le destructeur j'ai une exception "Violation d'accès à l'adresse ...". Comment détruire ce dialogue et supprimer le pointeur?

Répondre

1

Si quelqu'un est intéressé comme moi sur ce problème, la solution est simple. En fait, vous n'avez pas besoin de supprimer le pointeur CFindReplaceDislog * après l'avoir utilisé. Une fois fermé, il reçoit le message WM_NCDESTROY.

Et dans la mesure où il est dérivé de CWnd, le gestionnaire CWnd :: OnNcDestroy() est appelé. Dans la dernière ligne, il appelle PostNcDestroy() qui ne fait rien dans CWnd, mais surchargé dans CFindReplaceDialog. Là, il supprime 'ce' pointeur comme ceci:

void CFindReplaceDialog::PostNcDestroy() 
{ 
    ASSERT(m_hWnd == NULL); 
    delete this; 
} 

Ainsi, vous ne devez pas invoquer

delete(m_pFRDlg) 

partout