Ошибка отладки в.exe/wincore.cpp

Я делаю симулятор RT в VC++ 6.0. всякий раз, когда он выполняется, без компьютера с открытой архитектурой (OAC, это контроллер шины в полете), программа выполняется правильно. Но при включенном OAC программа дает сбой отладочного подтверждения - в Debug/.exe/wincore.cpp в строке №. 980. в чем может быть проблема? Пожалуйста, предоставьте решение, если это возможно.

Это дополнительная функция DestroyWindow.

BOOL CWnd::DestroyWindow()
{
    if (m_hWnd == NULL)
        return FALSE;

    CHandleMap* pMap = afxMapHWND();
    ASSERT(pMap != NULL);
    CWnd* pWnd = (CWnd*)pMap->LookupPermanent(m_hWnd);
#ifdef _DEBUG
    HWND hWndOrig = m_hWnd;
#endif

#ifdef _AFX_NO_OCC_SUPPORT
    BOOL bResult = ::DestroyWindow(m_hWnd);
#else //_AFX_NO_OCC_SUPPORT
    BOOL bResult;
    if (m_pCtrlSite == NULL)
        bResult = ::DestroyWindow(m_hWnd);
    else
        bResult = m_pCtrlSite->DestroyControl();
#endif //_AFX_NO_OCC_SUPPORT

    // Note that 'this' may have been deleted at this point,
    //  (but only if pWnd != NULL)
    if (pWnd != NULL)
    {
        // Should have been detached by OnNcDestroy
#ifdef _DEBUG
//////////////////////////////HERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!///////////////////
        ASSERT(pMap->LookupPermanent(hWndOrig) == NULL); //line 980
#endif
    }
    else
    {
#ifdef _DEBUG
        ASSERT(m_hWnd == hWndOrig);
#endif
        // Detach after DestroyWindow called just in case
        Detach();
    }
    return bResult;
}

2 ответа

Я думаю, что эта проблема связана с неправильным использованием CWnd::FromHwnd, например с сохранением полученного указателя и использованием его позже. Если что-то должно быть сохранено, оно должно быть HWND, а не CWnd*.

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

Проблема, скорее всего, в том, что вы куда-то звоните CWnd::GetSafeHwnd()и до сих пор использую это HWND обрабатывать в тот момент, когда окно разрушается. Другими словами, вы уничтожаете CWnd чья ручка все еще активна где-то еще.

Одним из решений является переопределение virtual BOOL DestroyWindow()и убедитесь, что вы отпустите ручку там.

Например, если вы показываете модальное диалоговое окно из плагина Acrobat, вы должны передать дескриптор окна в Acrobat, чтобы он знал, что вы находитесь в модальном режиме:

int CMyDialog::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
    if(CDialog::OnCreate(lpCreateStruct) == -1)
        return -1;
    // Put Acrobat into modal dialog mode
    m_AVdlgWin = AVWindowNewFromPlatformThing(AVWLmodal, 0, NULL, gExtensionID, GetSafeHwnd());
    AVAppBeginModal(m_AVdlgWin);
    AVWindowBecomeKey(m_AVdlgWin);
    return 0;
}

Конечно, вам нужно выполнить противоположное в DestroyWindow, чтобы убедиться, что внутренняя ручка отпущена:

BOOL CMyDialog::DestroyWindow()
{
    // Take Acrobat out of modal dialog mode, and release our HWND
    AVAppEndModal();
    AVWindowDestroy(m_AVdlgWin);
    return CDialog::DestroyWindow();
}

В этом примере предполагается, что CMyDialog всегда модальный.

Если вам не удалось освободить ручку, полученную GetSafeHwndВот тогда вы получите ошибку утверждения. Что именно означает выпуск ручки, зависит от того, что вы сделали с ней. Можно только догадываться.

Другие вопросы по тегам