日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

MFC模态对话框和非模态对话框

發布時間:2024/1/1 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MFC模态对话框和非模态对话框 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

下面是一個我的手寫的模態對話框和非模態對話框圖:

模態對話框是指當其顯示時,程序會暫停執行,直到關閉這個模態對話框后,才能繼續執行程序中其他任務。非模態對話框是指當其顯示時,允許轉而執行程序中其他任務,而不用關閉這個對話框。?

????模態對話框的創建:創建模態對話框需要調用CDialog類的成員函數:DoModal,該函數的功能是創建并顯示一個模態對話框,其返回值將作為CDialog類的另一個成員函數:EndDialog的參數,后者的功能是關閉模態對話框。一般顯示模態對話框的實現代碼如下:

void CASCEView::OnDialog()

{

???????? CASCEDlg dlg;

???????? dlg.DoModal();

}?

非模態對話框的創建:要創建非模態對話框就需要利用CDialog類的Create成員函數,該函數有以下兩種形式的聲明:

virtual BOOL Create(

?? LPCTSTR lpszTemplateName,

?? CWnd* pParentWnd = NULL

);

virtual BOOL Create(

?? UINT nIDTemplate,

?? CWnd* pParentWnd = NULL

);?

??? 由上可知,CDialog::Create函數的第一個參數可以是對話框資源的ID(nIDTemplate),或者也可以是對話框模板的名稱(lpszTemplateName);而第二個參數指定了對話框的父窗口,如果其值是NULL,則對話框的父窗口就是主應用程序窗口。

????當利用Create函數創建非模態對話框時,我們還需要接著調用ShowWindow函數來將這個對話框顯示出來;而利用DoModal創建的模態對話框之所以不用,是因為DoModal函數本身就有顯示模態對話框的作用。同時我們不能像模態對話框那樣將對話框定義成對象,如下代碼是顯示不出非模態對話框的:

void CASCEView::OnDialog()

{

???????? CASCEDlg dlg;

???????? dlg.Create(IDD_DIALOG1, this);

???????? dlg.ShowWindow(SW_SHOW);

}?

????因為這里創建的非模態對話框對象dlg是一個局部對象,當程序執行時,會依次執行各條代碼,當OnDialog函數執行結束時,dlg這個對象的生命周期也就玩玩了,它就會銷毀與之相關聯的對話框資源,對話框自然就顯示不出來啦!而模態對話框之所以能夠顯示,是因為當執行到調用DoModal函數以顯示模態對話框時,程序就會暫停執行,直到模態對話框關閉之后,程序才繼續向下執行。而這之前,dlg還沒銷毀。

??? 因此,在創建非模態對話框時,不能將對話框對象定義成局部變量,解決方法有二:一是把對話框對象定義成CASCEView類的成員變量;二是把它定義成指針,在堆上分配內存,如下:

void CASCEView::OnDialog()

{

???????? CASCEDlg *pDlg = new CASCEDlg;

???????? pDlg->Create(IDD_DIALOG1, this);

???????? pDlg->ShowWindow(SW_SHOW);

}?

??? 但是這又引入了新的問題:我們必須釋放pDlg占用的資源,否則會造成內存泄漏!況且這里pDlg還是一個局部指針變量,當它的生命周期結束時,在程序中就無法再引用它所指向的那塊內存了。解決方法同樣有兩個:一是將pDlg定義成CASCEView類的成員變量,然后在CASCEView類的析構函數中調用delete函數釋放它指向的內存;二是在CASCEDlg類中重載PostNcDestroy虛函數,釋放this指針指向的內存:

void CASCEDlg::PostNcDestroy()

{

???????? delete this;

???????? CDialog::PostNcDestroy();

}?

????還有一點需要注意的是:當單擊對話框上的默認OK按鈕時,兩種對話框都會消失。但對于模態對話框而言,此時對話框窗口對象被銷毀了;而對非模態對話框來說,對話框窗口對象并未被銷毀,只是隱藏起來而已。?

??? 在非模態對話框中單擊OK按鈕后,程序會調用基類CDialog的OnOK函數,這是一個虛函數,后者又會調用EndDialog函數,這個函數用于終止模態對話框,但對于非模態對話框,這個函數只是使對話框窗口不可見,并不銷毀它。因此,對非模態對話框來說,如果有一個ID值為IDOK的按鈕,就必須重寫基類的OnOK虛函數,并在重寫的函數中調用DestroyWindow函數,以完成銷毀對話框的工作,同時注意不要再調用基類的OnOK函數。同理,如果非模態對話框中有一個ID值為IDCANCEL的按鈕,也必須重寫基類的OnCancel虛函數,并在重寫的函數中調用DestroyWindow函數,銷毀對話框,同時注意不要再調用基類的OnCancel函數了。?

???? 非模態對話框相對于模態對話框,他的創建和銷毀過程和模態對話框有一定的區別

先看一下MSDN的原文:

When?? you?? implement?? a?? modeless?? dialog?? box,?? always?? override?? the?? OnCancel?? member?? function?? and?? call?? DestroyWindow?? from?? within?? it.?? Don’t?? call?? the?? base?? class?? CDialog::OnCancel,?? because?? it?? calls?? EndDialog,?? which?? will?? make?? the?? dialog?? box?? invisible?? but?? will?? not?? destroy?? it.?? You?? should?? also?? override?? PostNcDestroy?? for?? modeless?? dialog?? boxes?? in?? order?? to?? delete?? this,?? since?? modeless?? dialog?? boxes?? are?? usually?? allocated?? with?? new.?? Modal?? dialog?? boxes?? are?? usually?? constructed?? on?? the?? frame?? and?? do?? not?? need?? PostNcDestroy?? cleanup.

MS的指示:非模態對話框需要重載函數OnCanel,并且在這個函數中調用DestroyWindow。并且不能調用基類的OnCancel,因為基類的OnCancel調用了EndDialog這個函數,這個函數是針對模態對話框的。

還有一個必須重載的函數就是PostNcDestroy,這也是一個虛函數,通常的非模態對話框是用類的指針,通過new創建的,這就需要在PostNcDestroy函數中delete掉這個指針。?

了解了理論過后,下面我們就可以用代碼實現一下非模態對話框的創建和銷毀過程:

//建立

//主框架中:

CTestDlg *pDlg=new CTestDlg;

pDlg->Create(IDD_TESTDLG,this);

pDlg->ShowWindow(SW_SHOW);?

//對話框中:

void CTestDlg::OnCancel()

{

???? DestroyWindow();

}

void CTestDlg::PostNcDestroy()

{

???? CDialog::PostNcDestroy();

???? delete this;

}?

如果要在點擊按鈕的情況下,銷毀非模態對話框,只需要把按鈕的事件映射到OnCancel函數即可。

以下是一點資料供參考:?

MFC應用程序中處理消息的順序

1.AfxWndProc()?????? 該函數負責接收消息,找到消息所屬的CWnd對象,然后調用AfxCallWndProc?

2.AfxCallWndProc()?? 該函數負責保存消息(保存的內容主要是消息標識符和消息參數)供應用程序以后使用,然后調用WindowProc()函數?

3.WindowProc()?????? 該函數負責發送消息到OnWndMsg()函數,如果未被處理,則調用DefWindowProc()函數?

4.OnWndMsg()???????? 該函數的功能首先按字節對消息進行排序,對于WM_COMMAND消息,調用OnCommand()消息響應函數,對于WM_NOTIFY消息調用OnNotify()消息響應函數。任何被遺漏的消息將是一個窗口消息。OnWndMsg()函數搜索類的消息映像,以找到一個能處理任何窗口消息的處理函數。如果OnWndMsg()函數不能找到這樣的處理函數的話,則把消息返回到WindowProc()函數,由它將消息發送給DefWindowProc()函數?

5.OnCommand()?????? 該函數查看這是不是一個控件通知(lParam參數不為NULL,如果lParam參數為空的話,說明該消息不是控件通知),如果它是,OnCommand()函數會試圖將消息映射到制造通知的控件;如果他不是一個控件通知(或者如果控件拒絕映射的消息)OnCommand()就會調用OnCmdMsg()函數?

6.OnCmdMsg()???????? 根據接收消息的類,OnCmdMsg()函數將在一個稱為命令傳遞(Command Routing)的過程中潛在的傳遞命令消息和控件通知。例如:如果擁有該窗口的類是一個框架類,則命令和通知消息也被傳遞到視圖和文檔類,并為該類尋找一個消息處理函數?

MFC應用程序創建窗口的過程

1.PreCreateWindow()?? 該函數是一個重載函數,在窗口被創建前,可以在該重載函數中改變創建參數 (可以設置窗口風格等等)?

2.PreSubclassWindow() 這也是一個重載函數,允許首先子分類一個窗口?

3.OnGetMinMaxInfo()?? 該函數為消息響應函數,響應的是WM_GETMINMAXINFO消息,允許設置窗口的最大或者最小尺寸?

4.OnNcCreate()???????? 該函數也是一個消息響應函數,響應WM_NCCREATE消息,發送消息以告訴窗口的客戶區即將被創建?

5.OnNcCalcSize()?????? 該函數也是消息響應函數,響應WM_NCCALCSIZE消息,作用是允許改變窗口客戶區大小?

6.OnCreate()?????????? 該函數也是一個消息響應函數,響應WM_CREATE消息,發送消息告訴一個窗口已經被創建?

7.OnSize()???????????? 該函數也是一個消息響應函數,響應WM_SIZE消息,發送該消息以告訴該窗口大小已經發生變化?

8.OnMove()???????????? 消息響應函數,響應WM_MOVE消息,發送此消息說明窗口在移動?

9.OnChildNotify()???? 該函數為重載函數,作為部分消息映射被調用,告訴父窗口即將被告知一個窗口剛剛被創建?

MFC應用程序關閉窗口的順序(非模態窗口)?

1.OnClose()?????? 消息響應函數,響應窗口的WM_CLOSE消息,當關閉按鈕被單擊的時候發送此消息?

2.OnDestroy()???? 消息響應函數,響應窗口的WM_DESTROY消息,當一個窗口將被銷毀時,發送此消息?

3.OnNcDestroy()?? 消息響應函數,響應窗口的WM_NCDESTROY消息,當一個窗口被銷毀后發送此消息?

4.PostNcDestroy() 重載函數,作為處理OnNcDestroy()函數的最后動作,被CWnd調用?

MFC應用程序中打開模式對話框的函數調用順序?

1.DoModal()???????????? 重載函數,重載DoModal()成員函數?

2.PreSubclassWindow()??? 重載函數,允許首先子分類一個窗口?

3.OnCreate()???????????? 消息響應函數,響應WM_CREATE消息,發送此消息以告訴一個窗口已經被創建?

4.OnSize()?????????????? 消息響應函數,響應WM_SIZE消息,發送此消息以告訴窗口大小發生變化?

5.OnMove()?????????????? 消息響應函數,響應WM_MOVE消息,發送此消息,以告訴窗口正在移動?

6.OnSetFont()?????????? 消息響應函數,響應WM_SETFONT消息,發送此消息,以允許改變對話框中控件的字體?

7.OnInitDialog()???????? 消息響應函數,響應WM_INITDIALOG消息,發送此消息以允許初始化對話框中的控件,或者是創建新控件?

8.OnShowWindow()???????? 消息響應函數,響應WM_SHOWWINDOW消息,該函數被ShowWindow()函數調用?

9.OnCtlColor()?????????? 消息響應函數,響應WM_CTLCOLOR消息,被父窗口發送已改變對話框或對話框上面控件的顏色?

10. OnChildNotify()???? 重載函數,作為WM_CTLCOLOR消息的結果發送?

MFC應用程序中關閉模式對話框的順序?

1.OnClose()???????? 消息響應函數,響應WM_CLOSE消息,當"關閉"按鈕被單擊的時候,該函數被調用?

2.OnKillFocus()???? 消息響應函數,響應WM_KILLFOCUS消息,當一個窗口即將失去鍵盤輸入焦點以前被發送?

3.OnDestroy()?????? 消息響應函數,響應WM_DESTROY消息,當一個窗口即將被銷毀時,被發送?

4.OnNcDestroy()???? 消息響應函數,響應WM_NCDESTROY消息,當一個窗口被銷毀以后被發送?

5.PostNcDestroy()?? 重載函數,作為處理OnNcDestroy()函數的最后動作被CWnd調用?

打開無模式對話框的順序?

1.PreSubclassWindow()???? 重載函數,允許用戶首先子分類一個窗口?

2.OnCreate()???????????? 消息響應函數,響應WM_CREATE消息,發送此消息以告訴一個窗口已經被創建?

3.OnSize()?????????????? 消息響應函數,響應WM_SIZE消息,發送此消息以告訴窗口大小發生變化?

4.OnMove()?????????????? 消息響應函數,響應WM_MOVE消息,發送此消息以告訴窗口正在移動?

5.OnSetFont()???????????? 消息響應函數,響應WM_SETFONT消息,發送此消息以允許改變對話框中控件的字體?

以上這些的執行都是按給定的順序執行!

總結

以上是生活随笔為你收集整理的MFC模态对话框和非模态对话框的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。