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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

模态对话框和非模态对话框的消息循环分析

發(fā)布時(shí)間:2023/12/18 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 模态对话框和非模态对话框的消息循环分析 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1、非模態(tài)對(duì)話框和父窗口共享當(dāng)前線程的消息循環(huán)

2、模態(tài)對(duì)話框新建一個(gè)新的消息循環(huán),并由當(dāng)前消息循環(huán)派發(fā)消息,而父窗口。模態(tài)對(duì)話框屏蔽了用戶對(duì)它父窗口的操作,但是不是在消息循環(huán)里面屏蔽,所以給父窗口發(fā)送消息,父窗口還是可以接收得到。

3、調(diào)用模態(tài)對(duì)話框的窗口處理函數(shù)會(huì)被阻塞,但是新的消息循環(huán)仍然可以調(diào)用父窗口的消息處理函數(shù),所以,發(fā)送給父窗口的新消息仍然可以被及時(shí)處理。

/*****************************MFC模態(tài)對(duì)話框的消息循環(huán)***************************/

MFC模態(tài)對(duì)話框的消息循環(huán)
單線程程序, 當(dāng)主窗口響應(yīng)函數(shù)中彈出模態(tài)對(duì)話框時(shí),為什么主窗口響應(yīng)函數(shù)可能照常工作?

當(dāng)彈出模態(tài)對(duì)話框時(shí),線程的消息循環(huán)無法返回,父窗口的事件本應(yīng)沒人處理,應(yīng)該處于卡死狀態(tài),但實(shí)事上父窗口是可以正常響應(yīng)能接收到的消息的,比如計(jì)時(shí)器傳來的WM_TIMER 及系統(tǒng)托盤菜單傳回來的WM_COMMAND。

之前的消息循環(huán)無法返回是正確的,但模態(tài)對(duì)話框并不意味著死循環(huán),實(shí)事上,它在做另一個(gè)消息循環(huán)。


AfxInternalPumpMessage() 里面就是一個(gè)消息泵,包括消息的獲取與分發(fā):

?

?


只要有消息循環(huán)存在線程內(nèi)的所有窗口就會(huì)活過來。不管彈出多少個(gè)模態(tài)對(duì)話框,線程內(nèi)始終有一個(gè)消息循環(huán)為所以的窗口服務(wù)。

但這種形式帶來的那一個(gè)問題就是,如何關(guān)閉所有模態(tài)對(duì)話框并退出程序?

如果簡單地有EndDialog來關(guān)閉對(duì)話框,是無法讓所有的消息循環(huán)返回的。有一種做法是使用PostQuitMessage,使當(dāng)前的消息循環(huán)退出,消息循環(huán)收到WM_QUIT后,不當(dāng)退出本次循環(huán),還會(huì)給線程消息隊(duì)列Post另一個(gè)QUIT 消息,這樣消息循環(huán)就接二連三挨個(gè)退出了。

int CWnd::RunModalLoop(DWORD dwFlags)中的代碼片段可以說明這點(diǎn):

?/*************************windows 消息隊(duì)列,消息循環(huán),模態(tài)對(duì)話框**************/

Windows的消息隊(duì)列是基于線程的。


消息隊(duì)列,消息循環(huán):

線程是程序串行執(zhí)行的最小單位。

一個(gè)典型的Win32項(xiàng)目(不是MFC項(xiàng)目,只有一個(gè)窗口的項(xiàng)目),其中的消息循環(huán)會(huì)使用如下代碼實(shí)現(xiàn):


//代碼段1

MSG msg
BOOL bRet;

while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
{?
? ? if (bRet == -1)
? ? {
? ? ? ? // handle the error and possibly exit
? ? }
? ? else
? ? {
? ? ? ? TranslateMessage(&msg);?
? ? ? ? DispatchMessage(&msg);?
? ? }
}

GetMessage()是取得消息,如果沒有消息,線程阻塞在這里,不占用CPU。

DispatchMessage()是將消息分發(fā),分發(fā)到所有在這個(gè)線程中創(chuàng)建的窗口的窗口處理函數(shù)中去。 如果不需要分發(fā)消息,就不需要調(diào)用DispatchMessage(),例如線程中沒有窗口的情況。


線程消息循環(huán):

實(shí)際上,任何線程只要調(diào)用了上述代碼段1中的代碼,就已經(jīng)實(shí)現(xiàn)了消息循環(huán)的功能。更進(jìn)一步,其實(shí)只要調(diào)用GetMessage()函數(shù)就可以了。

即:

//代碼段2

BOOL bRet; ?MSG msg;
while( (bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
{?
if (bRet == -1 || WM_QUIT == msg.message){
// handle the error and possibly exit
break;
}
? ? ? ? }

在工作線程中,只要有代碼段2,就可以實(shí)現(xiàn)消息循環(huán)的功能了。

這是一個(gè)很方便的線程間異步通信的機(jī)制。給線程發(fā)消息用PostThreadMessage()。為什么去掉了DispatchMessage()呢,因?yàn)橐话闱闆r下,在工作線程中是不需要?jiǎng)?chuàng)建窗口的,不需要分發(fā)到窗口中去處理,能從線程的消息隊(duì)列里取得消息就足夠了。

如果設(shè)計(jì)線程的初衷為:當(dāng)某條件發(fā)生時(shí),讓工作線程開始工作,一直將工作完成,之后掛起,等待新條件的發(fā)生,等待時(shí)不占用CPU資源。 那么代碼段2所展示的機(jī)制就能很好的完成這樣的功能。 而且可以使多個(gè)工作線程都用同樣的機(jī)制實(shí)現(xiàn),彼此間協(xié)同工作,加之某種資源共享機(jī)制,可以實(shí)現(xiàn)一個(gè)異步的消息處理鏈。


模態(tài)對(duì)話框:

消息循環(huán)可以有多個(gè),可以在上一級(jí)消息循環(huán)的某個(gè)消息的處理過程中,局部創(chuàng)建一個(gè)消息循環(huán),模態(tài)對(duì)話框就是采用這種機(jī)制創(chuàng)建出來的。

一個(gè)線程可以有多個(gè)消息循環(huán),并行的消息循環(huán)顯然沒有意義,多個(gè)就是在消息循環(huán)中嵌套消息循環(huán)。

如代碼段1中的DispatchMessage函數(shù),將消息派發(fā)到窗口的消息處理函數(shù)中,WndProc1()。

現(xiàn)在假設(shè)在WndProc1()中創(chuàng)建一個(gè)消息循環(huán),并且只取得這個(gè)窗口本身的消息 GetMessage(&msg, hWnd, 0, 0),不必Dispatch了,因?yàn)橐呀?jīng)找到了目標(biāo)窗口,然后用這個(gè)窗口真正的消息處理函數(shù)去處理。 這樣模態(tài)對(duì)話框存在時(shí),處理了所有的窗口消息,創(chuàng)建模態(tài)對(duì)話框的窗口就一直得不到處理消息的機(jī)會(huì),模塊對(duì)話框就始終處于最上層,直到其主動(dòng)退出。

當(dāng)然,對(duì)模態(tài)對(duì)話框的這種解釋是簡化了的,實(shí)際過程可能復(fù)雜的多,取得的窗口消息至少要包含所有的子窗口的消息,也需要Dispatch到相應(yīng)的子窗口,等等。但是最基本的機(jī)制應(yīng)該就是這樣的。
/*********************模態(tài)對(duì)話框的消息機(jī)制****************************/

當(dāng)一個(gè)窗口時(shí)模態(tài)對(duì)話框時(shí),它的消息處理過程是有點(diǎn)特殊的。模式對(duì)話框都有自己的消息循環(huán),它阻塞的是原始的消息循環(huán),但是被對(duì)話框的消息循環(huán)接替。消息循環(huán)的本

質(zhì)是調(diào)用窗口過程,進(jìn)一步調(diào)用你的各種消息響應(yīng)函數(shù),所以無論有多少個(gè)消息循環(huán)存在,只要有一個(gè)消息循環(huán)有效,所有的消息響應(yīng)函數(shù)都能被調(diào)用,這也是為什么主窗口還能

響應(yīng)消息的緣故。多個(gè)消息循環(huán)的存在會(huì)產(chǎn)生某些副作用,比如消息重入,第一次消息響應(yīng)時(shí)彈出一個(gè)模式對(duì)話框,模式對(duì)話框的消息循環(huán)2取代原始消息循環(huán)1,假設(shè)此時(shí)主窗口

消息隊(duì)列里又有一個(gè)同樣的消息到來,消息循環(huán)2也會(huì)調(diào)用同樣的窗口過程(響應(yīng)函數(shù)),此時(shí)就能導(dǎo)致消息重入(因?yàn)榈谝淮芜M(jìn)入這個(gè)處理函數(shù)還沒有返回,本質(zhì)上這個(gè)響應(yīng)函數(shù)

被遞歸調(diào)用了),這也是能彈出多個(gè)模式對(duì)話框的原因。每個(gè)模式對(duì)話框都有自己的消息循環(huán),只有最后一個(gè)彈出對(duì)話框的消息循環(huán)才是活動(dòng)的消息循環(huán),其它所有消息循環(huán)(包

括主窗口、之前彈出的模式對(duì)話框)全被阻塞。這里的“阻塞”并不是消息被阻塞,而只是DispatchMessage一直沒有返回而已,但是其它的消息循環(huán)會(huì)接替這些工作。

/**********************MFC模態(tài)模式對(duì)話框,MessageBox消息循環(huán)原理,定時(shí)器TIMER消息響應(yīng)處理函數(shù)重入************/

一、MessageBox和定時(shí)器TIMER

MessageBox是Win32 API全局函數(shù),必須指定標(biāo)題和樣式。共有4個(gè)參數(shù)。沒有父窗口就NULL。返回值是int,看選什么按鈕。

比如:MessageBox( NULL, "選什么?", "標(biāo)題", MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2);

::表示全局函數(shù)。

在MFC中,可使用全局API函數(shù)::MessageBox(NULL,………),子程序會(huì)被暫時(shí)中斷在這個(gè)MessageBox上!其后的代碼無法運(yùn)行,等到MessageBox返回后會(huì)繼續(xù)運(yùn)行代碼。但父窗口可以被點(diǎn)出來,其它程序段可以運(yùn)行,比如其它按鈕。 ?因?yàn)镹ULL沒有指定父窗口,所以不會(huì)使父窗口無效!

MFC中直接使用MessageBox,則是使用CWnd類的MessageBox方法,這時(shí)父窗口無法被點(diǎn)出來,等同于::MessageBox(m_hWnd,………)。同時(shí)子程序被暫時(shí)中斷在這個(gè)MessageBox上。但關(guān)了其中一個(gè)消息框,則父窗就可以點(diǎn)出來了。 原理應(yīng)該是m_hWnd 指定了父窗,MessageBox使父窗口無效,然后進(jìn)入自己的消息循環(huán),關(guān)閉時(shí),使父窗有效。

在TIMER的響應(yīng)函數(shù)中,有MessageBox的話,則會(huì)暫時(shí)中斷在這個(gè)MessageBox上,但當(dāng)下個(gè)時(shí)間到時(shí),又會(huì)出現(xiàn)一個(gè)新的MessageBox,且也是暫時(shí)中斷在這個(gè)MessageBox上... ?即出現(xiàn)了多個(gè)消息響應(yīng)函數(shù)的例程!!多次重入!!每個(gè)例程都中斷在MessageBox上,MessageBox返回后,例程會(huì)繼續(xù)執(zhí)行到結(jié)束! ?各個(gè)消息框都是父窗的子窗,所以是平等的,所以各個(gè)消息框都可以點(diǎn)出來,但父窗點(diǎn)不出來。 ?可以關(guān)閉任何一個(gè)消息框,但是這個(gè)重入例程MessageBox之后的代碼不會(huì)運(yùn)行,要按倒序關(guān)閉其后的消息框后才會(huì)運(yùn)行。

二、消息框原理分析:參考《深入探討MFC消息循環(huán)和消息泵》和調(diào)試時(shí)斷點(diǎn)看代碼

注意:

MFC是單線程運(yùn)行的。

MFC內(nèi)部是有消息循環(huán)。

消息循環(huán)的DispatchMessage()會(huì)阻塞,需要等窗口消息處理函數(shù)處理完了以后,才會(huì)返回。

窗口消息處理函數(shù)是由操作系統(tǒng)調(diào)用的。

窗口消息處理函數(shù)是可以多次重入的!類似函數(shù)自己可以嵌套一樣。

單線程運(yùn)作:阻塞→重入→阻塞→重入。。。

時(shí)間到→操作系統(tǒng)放WM_TIMER到線程隊(duì)列→MFC消息循環(huán)DispatchMessage()阻塞→系統(tǒng)調(diào)用窗口消息處理函數(shù)OnTimer()處理完→消息循環(huán)繼續(xù)

操作系統(tǒng)一到時(shí)間就會(huì)放WM_TIMER到線程隊(duì)列。因?yàn)槭菃尉€程,如果窗口消息處理函數(shù)如果一直沒處理完,則WM_TIMER會(huì)堆積在隊(duì)列中。

OnTimer()中有消息框時(shí)情況就復(fù)雜了。MessageBox內(nèi)部是一個(gè)模態(tài)對(duì)話框,模態(tài)對(duì)話框有消息循環(huán)。

時(shí)間1到,系統(tǒng)放WM_TIMER到隊(duì)列

MFC程序主消息循環(huán)DispatchMessage()阻塞

操作系統(tǒng)調(diào)用第1個(gè)OnTimer()

MessageBox生成一個(gè)模態(tài)對(duì)話框?qū)ο?,顯示出來,運(yùn)行對(duì)話框內(nèi)的消息循環(huán)1

時(shí)間2到,系統(tǒng)放WM_TIMER到隊(duì)列

MessageBox1的消息循環(huán)1 DispatchMessage()阻塞

操作系統(tǒng)調(diào)用第2個(gè)OnTimer() (函數(shù)重入了!)

MessageBox生成一個(gè)模態(tài)對(duì)話框?qū)ο?,顯示出來,運(yùn)行對(duì)話框內(nèi)的消息循環(huán)2

時(shí)間3到,MessageBox2的消息循環(huán)2 DispatchMessage()阻塞,操作系統(tǒng)調(diào)用第3個(gè)OnTimer() (函數(shù)重入了!)。。。

即一個(gè)串一個(gè),只有最后一個(gè)消息框的消息循環(huán)在起作用,前面的消息循環(huán)全部阻塞了。

OnTimer()是主窗(父窗)函數(shù),所以各個(gè)MessageBox都是子窗,各個(gè)子窗是都可以點(diǎn)出來,但父窗會(huì)被子窗失效掉,所以父窗點(diǎn)不出來。

當(dāng)任何一個(gè)子窗關(guān)掉后,會(huì)使父窗有效,這時(shí)父窗可以點(diǎn)出來了。

三、消息框?qū)υ捒蜿P(guān)閉時(shí)原理

關(guān)閉時(shí)是怎樣?為什么關(guān)閉時(shí)是按倒序在執(zhí)行代碼?

MessageBox無法調(diào)試進(jìn)入內(nèi)部看代碼,就用模態(tài)對(duì)話框來代替吧:

CAboutDlg dlgAbout;

dlgAbout.DoModal(); ?// DoModal就會(huì)生成模態(tài)對(duì)話框

CDialog::DoModal()里面有CreateRunDlgIndirect()。

CWnd::CreateRunDlgIndirect里面有RunModalLoop()。

CWnd::RunModalLoop里面有消息循環(huán)AfxPumpMessage(),這里一直進(jìn)行消息循環(huán)!循環(huán)中還有CWnd::ContinueModal()判斷m_nFlags標(biāo)志看是否需要退出循環(huán)。

當(dāng)關(guān)閉對(duì)話框時(shí),如果點(diǎn)“確定”就是觸發(fā)CAboutDlg::OnOK(),點(diǎn)“X”就是觸發(fā)CAboutDlg::OnCancel()。 這兩個(gè)函數(shù)進(jìn)去都是運(yùn)行EndDialog()。

CDialog::EndDialog里面先運(yùn)行EndModalLoop(),然后是運(yùn)行::EndDialog()。

CWnd::EndModalLoop()里面有

m_nFlags &= ~WF_CONTINUEMODAL; ?把標(biāo)志設(shè)置成不再繼續(xù)運(yùn)行對(duì)話框

PostMessage(WM_NULL); ? 發(fā)送一個(gè)空消息以確保消息隊(duì)列中有消息,這樣消息循環(huán)不會(huì)因?yàn)闆]有消息而阻塞

::EndDialog()無法進(jìn)入看代碼,功能是把對(duì)話框關(guān)了不顯示,然后把父窗激活。

把對(duì)話框關(guān)了不顯示,這樣我們就點(diǎn)不到這個(gè)對(duì)話框,就不會(huì)再觸發(fā)窗口消息處理函數(shù)了。

所以清楚了:

點(diǎn)擊關(guān)閉其中一個(gè)消息框時(shí)(比如消息框1),生成了一個(gè)消息(這個(gè)消息是關(guān)聯(lián)這個(gè)消息框1的),“最后一個(gè)”消息框(比如消息框3)的消息循環(huán)DispatchMessage()這個(gè)消息后,操作系統(tǒng)重入消息框1對(duì)象的OnOK()或OnCancel(),設(shè)置m_nFlags標(biāo)志成不再繼續(xù)運(yùn)行,發(fā)送一個(gè)消息框1的消息WM_NULL,以及用::EndDialog()把消息框1銷毀了并把父窗激活。 ?

這個(gè)時(shí)候,這個(gè)消息框1對(duì)象仍存在,它的消息循環(huán)仍阻塞在DispatchMessage()中,只有等消息框3、消息框2的消息循環(huán)退出、OnTimer()退出后,才會(huì)從DispatchMessage()返回,然后發(fā)現(xiàn)m_nFlags不需要繼續(xù)運(yùn)行消息框了,于是退出消息循環(huán),然后退出消息框?qū)ο?#xff0c;然后退出OnTimer(),消息循環(huán)就又交還給MFC程序的主循環(huán)了。

四、非模式對(duì)話框

非模對(duì)話框沒有自己的消息循環(huán),也不會(huì)使父窗失效。

用Create()來顯示非模對(duì)話框,函數(shù)會(huì)立刻返回,所以必須要用new,這樣對(duì)話框?qū)ο缶捅A粼趦?nèi)存中。

如果用CAboutDlg dlgAbout;,則處理函數(shù)結(jié)束后,對(duì)象也被銷毀,即對(duì)話框一顯示就被關(guān)掉了。

CAboutDlg* pdlg = new CAboutDlg;

pdlg ->Create(IDD_ABOUTBOX); ? ? //非模式對(duì)話框,函數(shù)立刻返回,無自己的消息循環(huán)

pdlg->ShowWindow(SW_SHOW);

所以,關(guān)鍵是消息循環(huán)、消息處理函數(shù)重入。

/*****************模態(tài)對(duì)話框和非模態(tài)對(duì)話框的區(qū)別*********************/

模態(tài)對(duì)話框 操作模式上來講 模態(tài)對(duì)話框在關(guān)閉對(duì)話框(OnOk,OnCancel,OnClose)這三個(gè)消息產(chǎn)生之前不可對(duì)此對(duì)話框以外的對(duì)話框進(jìn)行操作 當(dāng)上面3個(gè)消息產(chǎn)生后系統(tǒng)負(fù)責(zé)刪除模態(tài)對(duì)話框資源 而非模態(tài)對(duì)話框可以進(jìn)行其他操作 必須在三個(gè)消息發(fā)生后自己在析構(gòu)函數(shù)里回收此對(duì)話框資源 比較麻煩模態(tài)對(duì)話框用DoModal()可以負(fù)責(zé)產(chǎn)生,顯示,銷毀窗口 非模態(tài)對(duì)話框需要調(diào)用Create()然后在創(chuàng)建的時(shí)候WS_VISIBLE或者在創(chuàng)建都調(diào)用ShowWindow 進(jìn)行顯示 最后調(diào)用DestroyWindow() 然后自己刪除掉對(duì)話框?qū)ο蟊容^麻煩

按工作方式不同,可將對(duì)話框分成兩類:
模式對(duì)話框(modal dialog box模態(tài)對(duì)話框):在關(guān)閉模式對(duì)話框之前,程序不能進(jìn)行其他工作(如一般的“打開文件”對(duì)話框)
無模式對(duì)話框(modeless dialog box 非模態(tài)對(duì)話框):模式對(duì)話框打開后,程序仍然能夠進(jìn)行其他工作(如一般的“查找與替換”對(duì)話框)
兩者的區(qū)別:
一. 非模態(tài)對(duì)話框的模板必須具有Visible風(fēng)格(Visible=True),否則對(duì)話框?qū)⒉豢梢?#xff0c;而模態(tài)對(duì)話框則無需設(shè)置該項(xiàng)風(fēng)格。在實(shí)際編程中更加保險(xiǎn)的辦法是調(diào)用CWnd::ShowWindow(SW_SHOW)來顯示對(duì)話框,而不管對(duì)話框是否具有Visible風(fēng)格。
二. 非模態(tài)對(duì)話框?qū)ο笫怯胣ew操作符來動(dòng)態(tài)創(chuàng)建的,而不是以成員變量的形式嵌入到別的對(duì)象中或以局部變量的形式構(gòu)建的。通常應(yīng)在對(duì)話框的擁有者窗口類內(nèi)聲明一個(gè)指向?qū)υ捒蝾惖闹羔槼蓡T變量,通過該指針可訪問對(duì)話框?qū)ο蟆?br /> 三. 通過調(diào)用CDialog::Create函數(shù)來啟動(dòng)對(duì)話框,而不是CDialog::DoModal,這是兩者之間區(qū)別的關(guān)鍵所在。由于Create函數(shù)不會(huì)啟動(dòng)新的消息循環(huán),對(duì)話框與應(yīng)用程序共用同一個(gè)消息循環(huán),這樣對(duì)話框就不會(huì)壟斷用戶輸入。Create在顯示了對(duì)話框后就立即返回,而DoModal是在對(duì)話框被關(guān)閉后才返回的。由于在Create返回后,不能確定對(duì)話框是否已關(guān)閉,這樣也就無法確定對(duì)話框?qū)ο蟮纳嫫?#xff0c;因此只好在堆棧中構(gòu)建對(duì)話框?qū)ο?#xff0c;而不能以局部變量的形式來構(gòu)建之。
四. 必須調(diào)用CWnd::DestroyWindow而不是CDialog::EndDialog來關(guān)閉非模態(tài)對(duì)話框。調(diào)用CWnd::DestroyWindow是直接刪除窗口的一般方法。由于缺省的CDialog::OnOK和CDialog::OnCancel函數(shù)均調(diào)用EndDialog,故程序員必須編寫自己的OnOK和OnCancel函數(shù)并且在函數(shù)中調(diào)用DestroyWindow來關(guān)閉對(duì)話框。
五. 因?yàn)槭怯胣ew操作符構(gòu)建非模態(tài)對(duì)話框?qū)ο?#xff0c;因此必須在對(duì)話框關(guān)閉后,用delete操作符刪除對(duì)話框?qū)ο蟆T谄聊簧弦粋€(gè)窗口被刪除后,框架會(huì)調(diào)用CWnd::PostNcDestroy,這是一個(gè)虛擬函數(shù),程序可以在該函數(shù)中完成刪除窗口對(duì)象的工作,具體代碼如下
void CModelessDialog::PostNcDestroy
{delete this; //刪除對(duì)象}
這樣,在刪除屏幕上的對(duì)話框后,對(duì)話框?qū)ο髮⒈蛔詣?dòng)刪除。擁有者就不必顯式地調(diào)用delete來刪除對(duì)話框?qū)ο罅恕?br /> 六. 必須有一個(gè)標(biāo)志表明非模態(tài)對(duì)話框是否打開的。這樣做的原因是用戶有可能在打開一個(gè)模態(tài)對(duì)話框的情況下,又一次選擇打開命令。程序根據(jù)標(biāo)志來決定是打開一個(gè)新的對(duì)話框,還是僅僅把原來打開的對(duì)話框激活。通常可以用擁有者窗口中的指向?qū)υ捒驅(qū)ο蟮闹羔樧鳛檫@種標(biāo)志,當(dāng)對(duì)話框關(guān)閉時(shí),給該指針賦NULL值,以表明對(duì)話框?qū)ο笠巡淮嬖诹恕?br /> 例如:
創(chuàng)建模態(tài)對(duì)話框
CTestDlg dlg;
dlg.DoModal();
創(chuàng)建非模態(tài)對(duì)話框
CTestDlg * dlg = new CTestDlg;
dlg->Create(IDD_TEST_DLG);
dlg->ShowWindow(SW_SHOW);?

總結(jié)

以上是生活随笔為你收集整理的模态对话框和非模态对话框的消息循环分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。