Отладка утверждения при закрытии приложения - PullRequest
0 голосов
/ 08 февраля 2019

При закрытии приложения я получаю следующее отладочное утверждение:

enter image description here Я отладил поток и обнаружил, что утверждение происходит в CWnd :: DestroyWindow ()

// Should have been detached by OnNcDestroy
#ifdef _DEBUG
            ASSERT(pMap->LookupPermanent(hWndOrig) == NULL);

Мой класс является производным от COleControl, который, в свою очередь, является производным от CWnd.

Создание объекта происходит в WinNET-форме .NET, а при закрытии приложения вызывается деструктор объекта ипришло подтверждение:

void CSimple::OnFinalRelease()
{
    if (!m_bFinalReleaseCalled)
    {
        m_bFinalReleaseCalled = TRUE;

        ReleaseCaches();

        CWnd::OnNcDestroy(); --> explicitly called OnNcDestroy()

        if (m_hWnd != NULL)
            DestroyWindow();

        CCmdTarget::OnFinalRelease();
    }

Я не уверен, что это правильное решение.Я также не уверен, что проблема в стороне .NET.

Ответы [ 2 ]

0 голосов
/ 11 февраля 2019

Никогда не звоните OnNcDestroy, прежде чем уничтожить окно.Вы никогда не должны вызывать этот обработчик самостоятельно.Это сообщение вызывается только из Windows.

OnNcDestroy всегда вызывается при вызове DestroyWindow.OnNcDestroy - это обработчик сообщения WM_NCDESTROY, и это последнее сообщение, которое получает окно.Эта функция всегда вызывает PostNCDestroy, что окончательно удаляет дескриптор окна из внутренних карт дескрипторов.

В этой последовательности должен произойти сбой DesroyWindow ...

0 голосов
/ 09 февраля 2019

Вызов CWnd::OnNcDestroy() из других функций неверен.Как правило, эти функции предназначены для ответа на сообщения окна.В этом случае, когда ваше окно будет уничтожено, система отправит сообщение WM_NCDESTROY (это будет последнее сообщение до того, как окно будет полностью разрушено)

Вы можете добавить ON_WM_NCDESTROY к карте сообщений вашего окна.И добавьте эту функцию:

void CMyWnd::OnNcDestroy() 
{
    CWnd::OnNcDestroy(); 
    ... do other cleanup
}

В этом случае вы можете попробовать вместо этого:

void CSimple::OnFinalRelease()
{
    if (m_hWnd != NULL)
        DestroyWindow();
    else
        PostNcDestroy(); // add this
    ...
}
...