我在一个基于SDI的程序中,在CMainFrame中的的OnClose中执行CFrameWnd::OnClose();时会出错。只有在调试时执行到这儿就会出错,程序运行(不是调试状态),就没有问题。经过跟踪,发现出错的代码是在
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
此时我的m_hWnd并不是无效的啊

解决方案 »

  1.   

    单看上边wincore里的代码很难看出问题出在哪儿。。- -。。
      

  2.   

    我比较的菜,看不懂调用堆栈中的东西,xianglitian
    (向立天),这位老大可否帮助分析一下啊CMainFrame::OnClose() line 580
    CWnd::OnWndMsg(unsigned int 16, unsigned int 0, long 0, long * 0x0013f348) line 1836
    CWnd::WindowProc(unsigned int 16, unsigned int 0, long 0) line 1596 + 30 bytes
    AfxCallWndProc(CWnd * 0x00032c50 {CMainFrame hWnd=0x00200622}, HWND__ * 0x00200622, unsigned int 16, unsigned int 0, long 0) line 215 + 26 bytes
    AfxWndProc(HWND__ * 0x00200622, unsigned int 16, unsigned int 0, long 0) line 379
    AfxWndProcBase(HWND__ * 0x00200622, unsigned int 16, unsigned int 0, long 0) line 220 + 21 bytes
    USER32! 77d18734()
    USER32! 77d18816()
    USER32! 77d28ea0()
    USER32! 77d28eec()
    NTDLL! 7c92e473()
    USER32! 77d2c228()
    UXTHEME! 5adc3bc2()
    UXTHEME! 5addc7f6()
    UXTHEME! 5adc1ac7()
    UXTHEME! 5addc2b1()
    USER32! 77d2f15c()
    USER32! 77d18734()
    USER32! 77d18816()
    USER32! 77d2a013()
    USER32! 77d2a998()
    CWnd::DefWindowProcA(unsigned int 274, unsigned int 61536, long 657267) line 1011 + 32 bytes
    CWnd::Default() line 258
    CWnd::OnSysCommand(unsigned int 61536, unsigned int 61536) line 418 + 15 bytes
    CFrameWnd::OnSysCommand(unsigned int 61536, long 657267) line 1046
    CWnd::OnWndMsg(unsigned int 274, unsigned int 61536, long 657267, long * 0x0013f908) line 1860
    CWnd::WindowProc(unsigned int 274, unsigned int 61536, long 657267) line 1596 + 30 bytes
    AfxCallWndProc(CWnd * 0x00032c50 {CMainFrame hWnd=0x00200622}, HWND__ * 0x00200622, unsigned int 274, unsigned int 61536, long 657267) line 215 + 26 bytes
    AfxWndProc(HWND__ * 0x00200622, unsigned int 274, unsigned int 61536, long 657267) line 379
    AfxWndProcBase(HWND__ * 0x00200622, unsigned int 274, unsigned int 61536, long 657267) line 220 + 21 bytes
    USER32! 77d18734()
    USER32! 77d2bdf1()
    USER32! 77d2927b()
    USER32! 77d292e3()
    UXTHEME! 5ade8895()
    UXTHEME! 5adc1ac7()
    UXTHEME! 5addc2b1()
    USER32! 77d2f15c()
    USER32! 77d18734()
    USER32! 77d18816()
    USER32! 77d2a013()
    USER32! 77d2a998()
    CWnd::DefWindowProcA(unsigned int 161, unsigned int 20, long 657267) line 1011 + 32 bytes
    CWnd::WindowProc(unsigned int 161, unsigned int 20, long 657267) line 1597 + 26 bytes
    AfxCallWndProc(CWnd * 0x00032c50 {CMainFrame hWnd=0x00200622}, HWND__ * 0x00200622, unsigned int 161, unsigned int 20, long 657267) line 215 + 26 bytes
    AfxWndProc(HWND__ * 0x00200622, unsigned int 161, unsigned int 20, long 657267) line 379
    AfxWndProcBase(HWND__ * 0x00200622, unsigned int 161, unsigned int 20, long 657267) line 220 + 21 bytes
    USER32! 77d18734()
    USER32! 77d18816()
    USER32! 77d189cd()
    USER32! 77d196c7()
    CWinThread::PumpMessage() line 853
    CWinThread::Run() line 487 + 11 bytes
    CWinApp::Run() line 400
    AfxWinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x00151f5e, int 1) line 49 + 11 bytes
    WinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x00151f5e, int 1) line 30
    WinMainCRTStartup() line 330 + 54 bytes
    KERNEL32! 7c817077()
      

  3.   

    你的OnClose函数中写了些什么?
      

  4.   

    KillTimer(1);
    KillTimer(2);
    CVideoViewView *pVideoView = (CVideoViewView*)m_SplitterWnd->GetPane(0,1); pVideoView->m_VideoListPane->ClearResources();
    CFrameWnd::OnClose();
    这是我close里的处理
    ClearResources是关闭一些正在播放的视频窗口。
    for (int i = 0; i < MAX_VIDEOPANE; i++)
    {
    if(m_VideoPane[i]->m_VideoType != 0)
    {
    //停止视频
    StopVideo(i);
    //清除播放列表
    m_VideoPane[i]->m_VideoWnd->ClearList();
    }
    if (m_VideoPane[i]->m_RecordedFlag)
    {
    m_VideoPane[i]->m_VideoWnd->StopRecord();
    }
    }
      

  5.   

    你的窗口是在你试图destroy的线程内创建的么?
    窗口需要在它被创建的线程内销毁,禁止跨线程操作
      

  6.   

    在OnClose里单步调试一下
    看看是哪句出的问题
      

  7.   

    void CMainFrame::OnClose() 
    {
    // TODO: Add your message handler code here and/or call default
    KillTimer(1);
    KillTimer(2);
    CVideoViewView *pVideoView = (CVideoViewView*)m_SplitterWnd->GetPane(0,1); pVideoView->m_VideoListPane->ClearResources();
    CFrameWnd::OnClose();<--------就是这句,跟进去之后就是这句bResult = ::DestroyWindow(m_hWnd);<------在这里出错,执行不下去了
    }
      

  8.   

    我的是一个SDI程序,在CMainFrame中创建了三个视图,每个视图中都有多个基于Dialog的窗口,窗口有自己create出来的,也有在资源中创建的,我在CmianFrame中调用OnClose,需要先去结束所有的子窗口吗?
      

  9.   

    有什么好的方法确定资源是否都已全部释放?能否从CMainFrame中的this指针看出有什么资源没有释放?我找了好久什么号得发现。所有new出来的对象我都在西沟函数中做了释放。
      

  10.   

    没有特别好的方法
    只有在编程的时候去注意
    否则很麻烦
    出你这种问题不是new的问题
    应该是com组件或类似的调用没有很好释放的造成的
    你可以注释掉一些代码运行看看然后逐步定位
    祝你好运
      

  11.   

    哦,谢谢啊,我已经初步定位问题可能是在我创建的视频控件上,是vlc控件,但里面又没有提供销毁控件的方法。
    但我在基于dialog中的创建的控件也没有去主动销毁它,但程序debug是,也没有在Onclose中卡住。。
    不知道他们之间有什么区别。
      

  12.   

    结贴有点晚,不好意思了。
    先谢谢大家的热情帮助了,我的问题应该算是解决了。
    由于用的控件无法控制,又不能释放多个控件对象,最终无奈的选择,直接在程序的OnClose中给程序发送WM_QUIT消息,不释放任何资源的情况下结束程序,让系统自己去回收资源。经过测试没有出现问题。也算是暴力的解决了问题。不知道大家对这种方法结束程序有什么看法。希望听听前辈们的一些想法。我在此静等大家的意见。我三天之后在结贴给大家分数。