簡體   English   中英

MFC應用程序結束后從CMainFrame進行析構函數調用時發生訪問沖突

[英]Access violation at destructor call from CMainFrame after end of mfc application

我正在為嵌入式Compact開發MFC應用程序。 目前,我嘗試添加一個對話框來關閉程序。 我的問題是我在CMainFrame的析構函數調用中遇到訪問沖突。 為了更清楚起見,首先提供了一段代碼。 這是我的應用程序的起點:

SWinApp.h

class SWinApp : public CWinApp
{
public:
    SWinApp();
    ~SWinApp(){};
public:
    virtual BOOL InitInstance();

protected:
    DECLARE_MESSAGE_MAP()
};

SWinApp.cpp

SWinApp::SWinApp():CWinApp()
{
}

BOOL SWinApp::InitInstance()
{
    CRuntimeClass* pRuntimeClass = RUNTIME_CLASS( SMainFrame );
    CObject* pObject = pRuntimeClass->CreateObject();
    ASSERT( pObject->IsKindOf( RUNTIME_CLASS( SMainFrame ) ) );
    m_pMainWnd = (SMainFrame*)pObject;
    m_pMainWnd->ShowWindow(SW_SHOWMAXIMIZED);
    return FALSE; // this is the next executed line after the access violation
}

BEGIN_MESSAGE_MAP(SWinApp, CWinApp)
END_MESSAGE_MAP()

SMainFrame.h

class SMainFrame : public CFrameWnd
{
    DECLARE_DYNCREATE(SMainFrame)
protected:
    SMainFrame();           
    ~SMainFrame();
    DECLARE_MESSAGE_MAP()
public:
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    afx_msg BOOL OnEraseBkgnd(CDC* pDC);
    virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

    afx_msg LRESULT OnDialogReady(WPARAM wParam, LPARAM lParam);

    afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);

    CurrentData* GetCurrentData(){return this->currentData;};
    Configuration* GetConfiguration(){return this->configuration;};
private:
    BOOL m_shown;   
    CurrentData* currentData;
    Configuration* configuration;
    std::map<UINT, CDialog*> views;
    UINT currentID;
};

SMainFrame.cpp

IMPLEMENT_DYNCREATE(SMainFrame, CFrameWnd)

    SMainFrame::SMainFrame()
{
    CString appName;
    appName.LoadStringW(IDS_APP_NAME);
    Create(NULL, appName);
    m_shown = FALSE;
    this->configuration = new Configuration();
    this->currentData = new CurrentData();
    this->currentID = IDD_MAIN_MENU_DIALOG;
    views.insert(std::make_pair(IDD_MAIN_MENU_DIALOG, new MainMenuDialog(this->configuration, this->currentData)));
    // There are more dialogs but for tests one is enough

}

SMainFrame::~SMainFrame()
{
    for(auto iterator:views)
    {
        delete iterator.second;
    }
    delete this->configuration;
    delete this->currentData; //Is executed properly
} // After this line an access violation occurres...


BEGIN_MESSAGE_MAP(SMainFrame, CFrameWnd)
    ON_MESSAGE(WM_USER_DIALOG_READY, &SMainFrame::OnDialogReady)
    ON_WM_CREATE()
    ON_WM_ACTIVATE()
END_MESSAGE_MAP()

// SMainFrame message handlers

int SMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    ModifyStyle(WS_CAPTION, 0, SWP_DRAWFRAME | SWP_NOZORDER );

    if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
        return -1;
    return 0;
}
afx_msg LRESULT SMainFrame::OnDialogReady(WPARAM wParam, LPARAM lParam)
{
    DialogThreadParams* params = (DialogThreadParams*)lParam;
    this->currentID = params->nextDialogID;
    m_shown = FALSE;
    this->ActivateFrame();
    return 0;
}

BOOL SMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
    if( !CFrameWnd::PreCreateWindow(cs) )
        return FALSE;

    cs.dwExStyle &= ~WS_EX_CLIENTEDGE | SWP_DRAWFRAME; 
    cs.style  =  WS_EX_CLIENTEDGE; 

    return TRUE;
}

void SMainFrame::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
{

    if(m_shown == FALSE)
    {
        m_shown = TRUE; 
        if(IsWindow(views[currentID]->m_hWnd))
        {
            views[currentID]->SetFocus();
        }
        else
        {
            views[currentID]->DoModal();
        }
    }
    CFrameWnd::OnActivate(nState, pWndOther, bMinimized);
}

MainMenuDialog是從StandardDialog繼承的類,該類是從CDialog繼承的。 我現在只發布部分代碼,因為這篇文章已經太長了(如果您需要更多信息,請告訴我哪一部分可能很有趣)...該對話框提供了關閉名為ShutdownDialog的應用程序的可能性(僅繼承自CDialog),並存儲為MainMenuDialog的私有變量:

ShutdownDialog* shutdownDialog;

在MainMenuDialog的構造函數中創建:

this->shutdownDialog = new ShutdownDialog();

我在單擊按鈕時顯示對話框:

void MainMenuDialog::OnClickedShutdownButton()
{
    shutdownDialog->DoModal();
}

並在MainMenuDialog的析構函數中刪除:

MainMenuDialog::~MainMenuDialog()
{
    delete shutdownDialog;
}

在ShutdowDialog中,我用以下代碼關閉應用程序:

AfxGetMainWnd()->PostMessage(WM_CLOSE);
EndDialog( 0 );

在此之前,一切正常。 該應用程序開始銷毀對象。 但是在完成對SMainFrame析構函數的調用后,我遇到了訪問沖突。 該程序不會停止,僅在“輸出”窗口中顯示一行。 它以語句“ return FALSE;”繼續。 在SWinApp InitInstance()中。

我知道兩次刪除對象或使用指針(其中依賴對象已被破壞)時都會發生訪問沖突,但是我無法弄清這里出了什么問題。 另外我不得不說SWinApp和SMainFrame是由一位同事創建的,我用SMainFrame中的對話框修改了零件。 我認為m_pMainWnd可能是問題,因為在對SMainFrame的析構函數調用之后,它必須是無效的指針。 所以我試着:

SMainFrame::~SMainFrame()
{
    for(auto iterator:views)
    {
        delete iterator.second;
    }
    delete this->configuration;
    delete this->currentData;
    AfxGetApp()->m_pMainWnd = NULL;
}

但是違例仍然發生...我搜索了Callstack窗口,但在視圖選項卡下找不到它。 很抱歉這是否太具體...但是自從幾個小時以來我一直在掙扎,不知道我可以嘗試...歡迎任何幫助!

更改AfxGetMainWnd()->PostMessage(WM_CLOSE); ::PostQuitMessage( 0 );

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM