2012-08-08 77 views
1

我都遵循這個問題做一個非模態/非模態對話框: How to display a non-modal CDialog?如何檢測無模式CDialog是否已關閉?

我使用MFC/C++在VS2008。我比C#和.net的流暢度高於MFC和C++。

我有一個菜單項在我的表單啓動對話框。只能有一個打開的對話框實例。該對話框顯示正常。我可以通過點擊拐角處的X來關閉它,當我關閉主窗體時它會關閉。我遇到的問題是在單擊X關閉對話框後無法再次打開對話框。我知道這是因爲指針永遠不會回到NULL。

我有這個在我的窗體的頭文件:

CChildDialog *m_pDialog; 

我有這部分我的窗體構造函數:

m_pDialog = NULL; 

當我在菜單項的驗證碼菜單項點擊方法(我從另一個SO修改它,因爲我只想要打開一個對話框的實例):

if(m_pDialog == NULL) 
{ 
    // Invoking the Dialog 
    m_pDialog = new CChildDialog(); 
    BOOL ret = m_pDialog->Create(IDD_CHILDDIALOG, this); 

    if (!ret) //Create failed. 
    { 
     AfxMessageBox(_T("Error creating Dialog")); 
    }  

    m_pDialog->ShowWindow(SW_SHOW); 
} 

現在我知道我需要執行此部分,並設置指針爲NULL,但我不知道在哪裏把這個:

// Delete the dialog once done 
delete m_pDialog; 
m_pDialog = NULL; 

我是否需要,如果對話框已被釋放,以保持監控?關閉對話框時是否觸發了父窗體?

+2

只需爲WM_DESTROY添加一個消息處理程序來重置指針。 – 2012-08-08 17:40:18

回答

3

如果你想與X關閉它後回收窗口的內容,你必須處理您的對話框中的WM_CLOSE消息:在打開的窗口中的代碼

void CChildDialog::OnClose() 
{ 
    ShowWindow(SW_HIDE); 
} 

然後:

if(m_pDialog == NULL) 
{ 
    // Invoking the Dialog 
    m_pDialog = new CChildDialog(); 
    BOOL ret = m_pDialog->Create(IDD_CHILDDIALOG, this); 

    if (!ret) //Create failed. 
    { 
     AfxMessageBox(_T("Error creating Dialog")); 
    }  
} 

m_pDialog->ShowWindow(SW_SHOW); //moved outside the if(m_pDialog == NULL) 

希望它可以幫助

0

我已經準備好了這個問題,並準備發佈它,但後來我有了一個想法,最終解決了我自己的問題。因此,對於誰比誰有檢測無模式對話框的關閉的問題,這是我做的:

void Form1::MenuItemMethod() 
{ 
    if(m_pDialog == NULL) 
    { 
     // Invoking the Dialog 
     m_pDialog = new CChildDialog(); 
     BOOL ret = m_pDialog->Create(IDD_CHILDDIALOG, this); 

     if (!ret) //Create failed. 
     { 
      AfxMessageBox(_T("Error creating Dialog")); 
     }  

     m_pDialog->ShowWindow(SW_SHOW); 
    } 
    else 
    { 
     // cannot check if visible at the beginning of method because 
     // pointer could be NULL and will throw an exception 

     if(m_pDialog->IsWindowVisible()) 
     { 
      return; 
     } 

     m_pDialog->DestroyWindow(); 
     m_pDialog = NULL; 
     MenuItemMethod(); 
    } 
} 

我剛剛結束了檢查,如果無模式對話框再次點擊窗體的菜單項後可見。如果可見,則不要做任何事情。如果不是,則銷燬現有的不可見對話框,將指針設置爲NULL,並再次遞歸調用該方法。由於指針現在爲NULL,它應該正常重新創建對話框,然後返回到正常操作。

+0

如果關閉對話框但會再次單擊菜單,會發生什麼情況?潛在的內存泄漏 – Jeeva 2012-08-09 07:39:09

0

你必須刪除存儲在PostNcDestroy這樣

void CChildDialog ::PostNcDestroy() 
{ 
    CDialog::PostNcDestroy(); 
    GetParent()->PostMessage(WM_WIN_CLOSED,0,0); 
    delete this; 
} 

並將用戶定義的消息發送到窗口關閉的父窗口。在父窗口中添加一個消息處理程序WM_WIN_CLOSED

LRESULT CMainDialog::OnMyMethod(WPARAM wParam, LPARAM lParam) 
{ 
    m_pDialog = NULL; 
    return 0; 
} 
1

如果要刪除無模式對話框,然後就這樣做。

如果您想在用戶關閉無模式對話框時刪除對話框的對象,則可以查看WM_PARENTNOTIFY。如果一個子窗口被銷燬並且子窗口沒有設置擴展窗口樣式WS_EX_NOPARENTNOTIFY,那麼Windows會將一個WM_PARENTNOTIFY與wParam = WM_DESTROY發送到父窗口。您應該在父窗口中爲該消息實現一個處理程序,並檢查它是否是正在銷燬的無模式對話框。