MFC CFindReplaceDialog уничтожение - PullRequest
0 голосов
/ 04 декабря 2008

Как правильно уничтожить указатель на CFindReplaceDialog объект?

Например, у меня есть класс:

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;
}

В справочной статье Visual Studio CFindReplaceDialog сказано, что объекты этого класса должны создаваться в куче с использованием оператора new. Затем должна быть вызвана Create функция-член.

Моя OnFind функция реагирует на закрытие этого диалога поиска. Вызывает DestroyWindow() функцию, пытается удалить объект диалога.

Но когда я пытаюсь вызвать DestoyWindow() в OnFind() или в деструкторе, у меня возникает исключение:

Нарушение доступа по адресу ...

Как уничтожить этот диалог и удалить указатель?

1 Ответ

2 голосов
/ 04 декабря 2008

Если кто-то, как и я, заинтересован в этой проблеме, решение простое. На самом деле вам не нужно удалять указатель CFindReplaceDislog* после его использования.

После закрытия он получает сообщение WM_NCDESTROY. И поскольку он получен из CWnd, вызывается CWnd::OnNcDestroy() обработчик. В последней строке он вызывает PostNcDestroy(), который ничего не делает в CWnd, но переопределяет в CFindReplaceDialog. Там он удаляет указатель this так:

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

Итак, вам не нужно никуда вызывать delete(m_pFRDlg).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...