2015-03-25 117 views
0

我正在開發嵌入式緊湊型mfc應用程序。目前我嘗試添加一個提供關閉程序的對話框。我的問題是,我從我的CMainFrame的析構函數調用得到訪問衝突。 首先讓它更清楚一段代碼。 這是我的應用程序的啓動點:在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的私有變量:在構造函數中創建MainMenuDialog的

ShutdownDialog* shutdownDialog; 

this->shutdownDialog = new ShutdownDialog(); 

我展示一個按鈕單擊該對話框:

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

而在MainMenuDialog的析構函數被刪除:

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

在ShutdowDialog我關閉應用程序與這段代碼:

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

直到這一切工作正常。應用程序開始銷燬對象。但是在完成對SMainFrame析構函數的調用之後,我得到一個訪問衝突。該程序不會停止,只是輸出窗口中的一行。它繼續聲明「返回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; 
} 

但仍然違反... occurres我 搜索調用堆棧窗口,但查看選項卡下無法找到它...... Sry基因爲這個長的帖子! 而且如果這太具體了......但是我幾個小時以來一直在掙扎,不知道我可以嘗試什麼......任何幫助都是值得歡迎的!

+0

不做AfxGetApp() - > m_pMainWnd = NULL;該框架爲你做。 – 2015-03-25 11:08:51

+1

你可以在調試模式下運行它,看看它崩潰的確切位置? – 2015-03-25 11:12:53

+0

嘗試更改AfxGetMainWnd() - > PostMessage(WM_CLOSE);到:: PostQuitMessage(0); – 2015-03-25 11:19:02

回答

0

變化AfxGetMainWnd()->PostMessage(WM_CLOSE);::PostQuitMessage(0);

相關問題