模式對話框與非模式對話框的區別


模式對話框就是不處理它就沒法處理父窗口,而非模式對話框就是不用先處理此對話框也可以處理父窗口.例子:在桌面上右擊我的電腦,選擇屬性,彈出系統屬性窗口,點擊下面的技術支持,彈出技術支持信息,現在再對系統屬性窗口進行操作就操作不了,這種叫做模式對話框;關閉技術支持信息,在系統屬性里選擇硬件,點擊設備管理器,彈出設備管理器窗口,現在再對系統屬性窗口進行操作仍然可以操作,這種就叫做非模式對話框。


在WIN32中,模式對話框的創建一般是使用DialogBox來進行創建的。而非模式對話框則是利用CreateWindow來創建的。在MFC或是WTL中,模式對話框一般是使用DoModal,而非模式對話框的創建則是使用Create。

一、使用中的區別

模式對話框創建后,程序的其他窗口便不能進行操作,必須將該窗口關閉后,其他窗口才能進行操作。而非模式對話框則無需這樣,它不強制要求用戶立即反應,而是與其他窗口同時接受用戶操作。

二、消息響應的區別

在消息響應方面,模式對話框和非模式對話框之間又有着很大的區別。模式對話框工作的時候,它有內部的消息泵機制,控件之間的交互不用我們人為的去控制,系統會幫助我們去處理。非模式對話框則像普通窗口一樣,則由WinMain中書寫的消息循環驅動。但由於是對話框,它對一些消息有特殊的處理。因此,在消息循環中,需要先對對話框提供截獲消息的機會。

While (GetMessage(&msg, NULL, 0, 0))

{

if (hDlgModeless == 0 || !IsDialogMessage(hDlgModeless, &msg))

{

    TranslateMessage(&msg);

    DispatchMessage( &msg);

}

}

如果當前取得的消息是對話框的消息,IsDialogMessage 將它交由對話消息處理函數處理,並返回TRUE。不需要再派發了。

注意:這個方法並不是很好用,因為當對話框過多的時候,處理起來就比較麻煩了。另一種處理的方法是利用子類化控件的方法,來處理控件間的交互。

三、銷毀的區別

模式對話框的銷毀是使用EndDialog,而非模式對話框的銷毀是使用DestroyWindow.。所以我們在銷毀對話框的時候,也要對其進行區別。

非模式對話框,用戶關閉對話框時,對話框消息處理函數將收到WM_CLOSE消息,接到后調用DestroyWindow以銷毀非模式對話框。

模式對話框,則一般響應IDOK和IDCANCEL。在PPC上,我們對於OK鍵和X鍵的處理要注意這點。

四、其他

非模態對話框的模板必須具有Visible風格,否則對話框將不可見,而模態對話框則無需設置該項風格。更保險的辦法是調用ShowWindow(hDialog, SW_SHOW)來顯示對話框,而不管對話框是否具有Visible風格。

非模態對話框對象是用new操作符在堆中動態創建的,而不是以成員變量的形式嵌入到別的對象中或以局部變量的形式構建在堆棧上。通常應在對話框的擁有者窗口類內聲明一個指向對話框類的指針成員變量,通過該指針可訪問對話框對象。

通過調用Create函數來啟動對話框,而不是DoModal,這是模態對話框的關鍵所在。由於Create函數不會啟動新的消息循環,對話框與應用程序共用同一個消息循環,這樣對話框就不會壟斷用戶的輸入。Create在顯示了對話框后就立即返回,而DoModal是在對話框被關閉后才返回的。眾所周知,在MFC程序中,窗口對象的生存期應長於對應的窗口,也就是說,不能在未關閉屏幕上窗口的情況下先把對應的窗口對象刪除掉。由於在Create返回后,不能確定對話框是否已關閉,這樣也就無法確定對話框對象的生存期,因此只好在堆中構建對話框對象,而不能以局部變量的形式來構建之。

因為是用new操作符構建非模態對話框對象,因此必須在對話框關閉后,用delete操作符刪除對話框對象。

必須有一個標志表明非模態對話框是否是打開的。這樣做的原因是用戶有可能在打開一個模態對話框的情況下,又一次選擇打開命令。程序根據 標志來決定是打開一個新的對話框,還是僅僅把原來打開的對話框激活。通常可以用擁有者窗口中的指向對話框對象的指針作為這種標志,當對話框關閉時,給該指 針賦NULL值,以表明對話框對象已不存在了。

注意:在C++編程中,判斷一個位於堆中的對象是否存在的常用方法是判斷指向該對象的指針是否為空。這種機制要求程序員將指向該對象的指針初始化為NULL值,在創建對象時將返回的地址賦給該指針,而在刪除對象時將該指針置成NULL值。


非模
形式上 ①一個模式對話框是一個有系標題欄邊線等的出式窗口。在對話指定WS_POPUP, WS_SYSMENU, WS_CAPTION和 DS_MODALFRAME格。即使沒有指定WS_VISIBLE格,模式對話框也會被示。

對話框窗口,將送WM_INITDIALOG消息(如果指定對話框的DS_SETFONT格,有WM_SETFONT消息)給對話程。(對話框的窗口程由Windows系提供,用對話框窗口提供一個對話程由窗口調
用。)

對話框窗口被建之后,Windows使得它成一個激活的窗口,它保持激活直到對話調用::EndDialog函數對話框的運行或者Windows激活另一個用程序止,在激活,用或者
用程序不可以激活它的所屬窗口(Owner window)。
①一個無模式對話框是一個有系標題欄邊線等的出式窗口。在對話框模板指定WS_POPUP、WS_CAPTION、WS_BORDER和WS_SYSMENU格。如果沒有指定WS_VISIBLE格,無模式對話框不會自示出來。

②一個無模式
對話框既不會禁止所屬窗口,也不會送消息。當建一個模式對話,Windows使它成窗口,但用或者程序可以隨置活窗口。如果對話框失去激活,那么即使所屬窗口是活的,在Z軸順
序上,它仍然在所屬窗口之上。

創建 DoModal() Create()
銷毀 一個用程序通過調用::EndDialog函數來一個模式對話框。一般情況下,當用從系選擇了關(Close)命令或者按下了確(OK)或取消(CANCLE)按,::EndDialog被對話程所調用。調用::EndDialog,指定其參數nResult的,Windows將在對話框窗口后返回,一般,程序通返回判斷對話框窗口是否完成了任或者被用取消。

※ EndDialog(IDC_BUTTON_DEFAULT);我
們的代碼中EndDialog方法在指定的BUTTON處理事件結束時調用,來關閉對話框

用程序束之前,它必須銷所有的無模式對話框。使用::DestroyWindow一個無模式對話框,不是使用::EndDiaLog。一般來對話程響戶輸入,如用戶選擇了“取消”按則自動調用::DestroyWindow;如果用沒有有關作,則應用程序必須調用::DestroyWindow。

轉自:http://blog.csdn.net/gfsuper_2211/article/details/4223713

 

系統處理非模態對話框和模態對話框的區別

非模態對話框相對於模態對話框,他的創建和銷毀過程和模態對話框有一定的區別 先看一下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消息,發送此消息以允許改變對話框中控件的字體

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

轉自:http://blog.csdn.net/gfsuper_2211/article/details/4223696


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM