Ошибка отладки в .exe / wincore.cpp - PullRequest
0 голосов
/ 07 февраля 2011

Я делаю симулятор 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 ]

0 голосов
/ 04 ноября 2015

Скорее всего, проблема в том, что где-то вы звоните 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, тогда вы получите ошибку подтверждения. Что именно означает выпуск ручки, зависит от того, что вы сделали с ней. Можно только догадываться.

0 голосов
/ 13 марта 2011

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

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

...