2013-05-03 2 views
3

MS documentationothers) «ясно» гласит:CDialog - EndDialog из диалога MODELESS?

... Поскольку нормальные функции-члены OnOK и OnCancel объекта CDialog бы назвать EndDialog, убедитесь, что ваш немодальным диалоговое окно делает не назвать тех, функции и вместо переопределяет

Поскольку CDialog::OnOk эффективно вызывает CDialog::EndDialog, и этот метод выглядит следующим образом:

void CDialog::EndDialog(int nResult) 
{ 
    ASSERT(::IsWindow(m_hWnd)); 

    if (m_nFlags & (WF_MODALLOOP|WF_CONTINUEMODAL)) 
     EndModalLoop(nResult); 

    ::EndDialog(m_hWnd, nResult); 
} 

мы можем также проверить the docs for ::EndDialog что опять-таки "ясно" состояние:

диалоговые окна, созданные DialogBox, DialogBoxParam, DialogBoxIndirect и функции DialogBoxIndirectParam должны быть уничтожены с помощью функции EndDialog. Приложение вызывает EndDialog из процедуры диалога; функция не должна использоваться для любых других целей.

Тем не менее, у меня есть производный класс CDialog, который имеет поведение по умолчанию. OnOK и , казалось бы, все работает, когда я использую его немодальным/немодальным.

То есть: * Когда я закрываю (немодальное) диалоговое окно, оно закрывается/удаляется из представления. * Приложение не обнаруживает утечек памяти. (Сборка отладки MFC)

И что? Нужно ли мне предотвращать EndDialog и звонить DestroyWindow сам или нет?


Примечание: Я знаю, что говорят документы и «сеть». Это просто, что я еще не нашел , почему Мне нужно сделать это по-другому, и этот один класс должен использоваться для немодального и модального режима, поэтому не нужно делать что-либо другое, может быть удобно.

+1

Я подозреваю, что вы просачиваетесь в окно. Это не будет выглядеть как утечка памяти в вашем приложении, потому что окна поддерживаются системой. Проверьте столбец «USER objects» в диспетчере задач, чтобы узнать, растет ли значение с течением времени. – arx

ответ

2

MSDN Docs для CDialog::OnOK ясно заявляет

Если вы реализуете кнопку OK в диалоговом окне безрежимного, вы должны переопределить метод OnOK и вызвать DestroyWindow внутри него. Не называйте метод базового класса, так как он вызывает EndDialog что делает диалоговое окно невидимым, но не уничтожает его

Таким образом, вы должны переопределить CDialog::OnOK и вызвать DestroyWindow() внутри - вот модифицированный пример из MSDN:

class CDlg : public CDialog 
{ 
    ... 
    BOOL m_bModal; 
    ... 
} 

CDlg::CDlg(CWnd* pParent /*=NULL*/) 
: CDialog(CDlg::IDD, pParent) 
{ 
    ... 
    m_bModal = FALSE; 
    ... 
} 

INT_PTR CDlg::DoModal() 
{ m_bModal = TRUE; 
    const INT_PTR rval = CDialog::DoModal(); 
    m_bModal = FALSE; 
    return rval; 
} 

void CDlg::OnOK() 
{ 
    if (!UpdateData(TRUE)) 
    { 
     TRACE(_T("UpdateData failed during dialog termination\n")); 
     // The UpdateData routine will set focus to correct item 
     return; 
    } 
    if (m_bModal) 
     EndDialog(IDOK); 
    else 
     DestroyWindow(); 
} 

void CDlg::OnCancel() 
{ 
    if (m_bModal) 
     EndDialog(IDCANCEL); 
    else 
     DestroyWindow(); 
} 
+0

Спасибо. Я думаю, что я не проверял метод docs здесь. Теперь это кажется довольно ясным. –

+0

@MartinBa обновленный код выше для обработки модальных и немодальных диалогов –

+0

Вы положительно, что это работает? В моем оригинальном случае я перешел через функцию «CDialog :: EndDialog», и я думаю, что я помню, что эти флаги также устанавливаются в моем немодальном диалоговом окне, созданном с помощью «Create» ... у меня здесь нет кода, чтобы проверить этот atm. –