OnTime消息

id="Topic_Zone" marginwidth="0" marginheight="0" src="/u/AD/Topic_Zone.aspx" frameborder="0" width="100%" scrolling="no" height="0">
發表於:2007-06-22 12:39:541樓 得分:0
f()函數一定會進入多次
 
  • sangwf
  • 等 級:
發表於:2007-06-22 12:51:572樓 得分:0
那就比較奇怪了,爲什麼會進入多次呢。既然主程序是單線程的,同時只能有一個地方在執行,而彈出對話框會令程序阻塞到那裏,其他的函數執行不進去纔對。

另外,我剛做了測試,在彈出多個對話框時,線程數並沒有增加,說明ontimer肯定不是通過多線程機制實現,這是怎麼一回事呢?
 
發表於:2007-06-22 12:57:283樓 得分:0
應該是異步或消息通知機制吧,windows裏面全部都是消息
 
  • appleboyecho
  • 等 級:
發表於:2007-06-22 12:58:124樓 得分:0
WINDOWS在定時時間到後,會把WM_TIIMER消息放入應用程序的消息隊列當中,不管你的對話框是否關閉,也不管你執行什麼,因此,F函數肯定會進入多次的。
 
  • khler
  • 等 級:
發表於:2007-06-22 13:03:095樓 得分:0
誰說的主程序是單線程的?GUI程序都是CWinApp的一個實例,而CWinApp就是繼承自CWinThread
 
  • sangwf
  • 等 級:
發表於:2007-06-22 13:05:326樓 得分:0
你是說主程序是多線程的?就是我的對話框不關閉,照樣會處理消息隊列中的消息?

如果是這樣,f()會不會同時有多個在執行?那豈不等於是多線程?
 
發表於:2007-06-22 13:07:307樓 得分:0
在函數執行某處彈出一個模態對話框!
可以說只是把這個函數後面的代碼暫停執行!等待這個模態對話框關閉,然後恢復執行!
不是把當前線程掛起!

如果f()函數執行的時間很長,超過了定時器的週期,那會不會出現f()函數被進入多次呢!

當然會被多次進入!只不過下一次ontimer得在前一次的ontimer中的f()執行完後被調用!


 
  • sangwf
  • 等 級:
發表於:2007-06-22 13:20:198樓 得分:0
那就是說模態對話框彈出以後,程序還可以繼續處理其他消息?

另外,如果我不彈出對話框,而是執行f()函數,那是不是會出現兩個f()函數都執行了一半?也就是出現同步問題?
 
  • sangwf
  • 等 級:
發表於:2007-06-22 13:22:549樓 得分:0
另外一個問題就是,主程序在進行消息處理時,肯定是要等待一個消息處理完之後再處理下一條消息的吧?而彈出對話框之後說明當前的消息還沒有處理完啊,怎麼會執行下一條呢?
 
發表於:2007-06-22 14:01:2810樓 得分:0
那是不是會出現兩個f()函數都執行了一半?
---------------------------------------
是的!

而彈出對話框之後說明當前的消息還沒有處理完啊,怎麼會執行下一條呢?
----------------------------------------------------------------
我的理解是就當彈出摸態對話框的時候會做些特殊處理了!
 
發表於:2007-06-22 14:04:3411樓 得分:0
具體是怎麼處理我就不知道!
畢竟程序是人家微軟寫的!
呵呵!

ps:別忘了結貼^_^
 
發表於:2007-06-22 14:18:0012樓 得分:0
樓上說的全不對!聽我的:
1首先程序本身是單線程,這一點錯誤也沒有!
2至於會連續彈出對話框,是因爲雖然對話框會將線程的消息派發阻塞,但是對話框(包括messagebox)也會有一個無限循環,用於getmessage(),dispatchmessage(),所以永遠不會阻礙主先程獲得,分派消息!
就是這樣,希望大家多重視一些基礎的windows原理機制,畢竟原理是很重要的。
 
  • sangwf
  • 等 級:
發表於:2007-06-22 14:34:5913樓 得分:0
2,如果主線程的派發阻塞了,就沒辦法發出ontimer消息了,又怎麼會彈出新對話框呢?

另外,f()會出現多個同時在執行麼?
 
發表於:2007-06-22 14:50:3214樓 得分:0
至於會連續彈出對話框,是因爲雖然對話框會將線程的消息派發阻塞
----------------------------------------------------------------------------
無語。。。。
呵呵!
 
  • sangwf
  • 等 級:
發表於:2007-06-22 14:59:1315樓 得分:0
是不是沒有表達清楚,解釋不通啊。
 
發表於:2007-06-22 15:01:3816樓 得分:0
定時消息是操作系統往線程隊列裏打的消息,不是你線程給自己往消息隊列裏發送的,就像鼠標消息一樣,你有見過什麼時候線程阻塞得連鼠標消息都接收不了了麼?  
     
      還有樓上的zhejiang9(Why   not?),你覺得我哪裏說錯了麼?你最好自己做程序試驗一下,要是我錯了歡迎你提出來。  

 
發表於:2007-06-22 15:05:5717樓 得分:0
我給你解釋下吧!
按照cymvp()   這位老兄的說法是:
如果你在程序裏彈出了100個模態對話框!
這個線程就會有101個消息循環;
。。。。想想都假!
 
發表於:2007-06-22 15:09:2418樓 得分:0
sangwf,你用vc的win32   application建立一個工程,然後在:


while   (GetMessage(&msg,   NULL,   0,   0))  
{
                                  ////////////******
if(msg.message==WM_try {
MessageBox(hWnd1, "主窗口發送WM_try ", " ",0);

}
////**************
if   (!TranslateAccelerator(msg.hwnd,   hAccelTable,   &msg))  
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

加上*****的那段語句,其中WM_try是我自定義的消息,你可以添加一下,然後在窗口函數中隨便哪個case下發送這個消息,比如:


case   IDM_ABOUT:
if(hWnd==hWnd1)
{

PostMessage(hWnd1,WM_try,0,0);///將消息放入隊列就返回;
//Sleep(3000);
DialogBox(hInst,   (LPCTSTR)IDD_ABOUTBOX,   hWnd,   (DLGPROC)About);

}

然後你就會發現,Wm_try消息仍會接受,但是不會出來“主窗口發送WM_try“的對話框,因爲Wm_try消息是messagebox幫你接受的!
 
發表於:2007-06-22 15:14:5219樓 得分:0
zhejiang9(Why   not?)   請問你做試驗了麼?你真的懂這裏的消息循環麼?  

你要是不明白我給你講!這裏只有一個線程,當然只有一個消息循環,只是當你彈出對話框的時候,對話框阻塞了主線程的消息循環,而接替過來了消息循環,因爲它的內部也是一個無限的消息接收,派發機制。而你再彈出另一個對話框b的時候,對話框b又會接替過來消息循環,而把第一個對話框阻塞掉。這也是你爲什麼彈出第2個對話框後第一個對話框變得點擊無效了的原因。
 
發表於:2007-06-22 15:16:5220樓 得分:0
。。。。。。
你這是在阻塞線程主消息循環!
你把他都阻塞了!
你怎麼處理messagebox產生的停留在線程消息隊列中的消息
比如WM_PAINT等!
你畫都畫不了!去哪顯示去!
 
發表於:2007-06-22 15:18:5521樓 得分:0
呵呵!
程序我寫很多了!
試驗就不用了!

ps:寫了這麼久的VC程序了,我沒你想象的那麼面!哈哈!
 
發表於:2007-06-22 15:21:0322樓 得分:0
zhejiang9(Why   not?)   ,請問你做試驗了麼?做了實驗再回來說!
線程主消息循環裏的那段messagebox代碼根本就不會執行!因爲主線程的消息循環里根本接受不到wm_try的消息!
作計算機怎麼能不動手阿!
 
發表於:2007-06-22 15:22:1523樓 得分:0
哈哈!
我寫過這方面的程序!
要不我能隨便亂講嘛!
 
發表於:2007-06-22 15:25:3224樓 得分:0
呵呵我也沒別的意思,但是vc把上面的東西都封裝好了,這塊東西基本是用不到的。
關於對話框的消息循環網上的資料很多,可以去看看,我說的基本是沒有問題的,要是有什麼問題,可以繼續討論。
 
發表於:2007-06-22 15:26:1325樓 得分:0
從上面看下來一把汗阿,總算cymvp()說出正確答案來了。
DoModal和MessageBox的自身代碼裏面有消息循環(負責消息取出和處理),當一個MessageBox還存在的時候,CPU還在處理MessageBox內部的代碼,當你有任何消息的時候到來,MessageBox內部的代碼會負責將之處理掉。
給你一個簡單的例子

CxxxDlg::OnTimer(UINT   nIDEvent)
{
static   int   i   =   0,j;
j   =   i++;
if   (i==2)   KillTimer(nIDEvent);
MessageBox( "! ");
i++;
CString   str;
str.Format( "%d,%d/r/n ",j,i);
::OutputDebugString(str);
}

知道結果是什麼?調試一下,看看輸出框結果,想想爲什麼會是這樣,很容易理解的。
 
發表於:2007-06-22 15:27:5826樓 得分:0
謝謝樓上的朋友,真想頂你一下!
 
發表於:2007-06-22 15:28:4727樓 得分:0
CxxxDlg::OnTimer(UINT   nIDEvent)
{
static   int   i   =   0;
int   j;
j   =   i++;
if   (i==2)   KillTimer(nIDEvent);
MessageBox( "! ");
i++;
CString   str;
str.Format( "%d,%d/r/n ",j,i);
::OutputDebugString(str);
}

錯了,第二個j不是static的。
 
發表於:2007-06-22 15:34:1728樓 得分:0
~—~
好象是我錯了!
cymvp()     sorry,sorry
學習學習!
對樓主誤導表示歉意!
 
發表於:2007-06-22 15:39:1729樓 得分:0
客氣,交流沒有對錯哈
 
發表於:2007-06-22 15:43:2530樓 得分:0
上面好像還有一點沒有指明,f()不可能同時執行,必須在上一次f()執行完後纔可能執行下次,除非你的f()裏面也處理了消息循環,處理消息循環大致的代碼如下:
while   (GetMessage(&msg,   NULL,   0,   0))  
{
if   (!TranslateAccelerator(msg.hwnd,   hAccelTable,   &msg))  
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

基本上就是cymvp()   舉的例子。
當初我初學時也被這個問題困擾了很久……
 
發表於:2007-06-22 15:44:5431樓 得分:0
呵呵!
沒白爭論這麼久!
雖然自己錯了也很爽!
哈哈!
繼續努力!

 
  • sangwf
  • 等 級:
發表於:2007-06-22 15:45:5632樓 得分:0
謝謝cymvp,雖然沒有彈出MessageBox(hWnd1, "主窗口發送WM_try ", " ",0);,但我怎麼能判斷出時AboutBox處理的呢?
 
發表於:2007-06-22 15:49:2833樓 得分:0
cymvp()   (   )   信譽:100         Blog       加爲好友     2007-06-22   15:14:52     得分:   0    

      zhejiang9(Why   not?)   請問你做試驗了麼?你真的懂這裏的消息循環麼?  

你要是不明白我給你講!這裏只有一個線程,當然只有一個消息循環,只是當你彈出對話框的時候,對話框阻塞了主線程的消息循環,而接替過來了消息循環,因爲它的內部也是一個無限的消息接收,派發機制。而你再彈出另一個對話框b的時候,對話框b又會接替過來消息循環,而把第一個對話框阻塞掉。這也是你爲什麼彈出第2個對話框後第一個對話框變得點擊無效了的原因。
-------------------------------------------------------------------------------

最後一句有問題,“第一個對話框變得點擊無效”是因爲DoModal將第一個對話框EnableWindow(FALSE)的緣故,如果你在第二個對話框弄個按鈕,點一下將第一個對話框EnableWindow(TRUE)的話,第一個對話框依然是完全正常的。
DoModal和MessageBox以及上面自己手動加的消息循環代碼都是一視同仁的,不會只爲自身服務……

   
 
 
  • sangwf
  • 等 級:
發表於:2007-06-22 15:50:2434樓 得分:0
回的慢了,你們都討論了這麼多。。
 
發表於:2007-06-22 15:54:2935樓 得分:0
w_anthony()  
我也想頂你下!
對了!
我怎麼找這方面的資料都找不着呢!
有什麼好書介紹下!
 
發表於:2007-06-22 15:55:4736樓 得分:0
關於f()能不能執行多次的問題,我倒是覺得可以執行多次,因爲我認爲窗口函數就是可以同時調用的,比如在:
case   IDM_ABOUT:
if(hWnd==hWnd1)
{

SendMessage(hWnd1,WM_try,0,0);///將消息放入隊列就返回;
....

用SendMessage()發給線程一個消息,當前的窗口函數就會被阻塞住(因爲SendMessage()必須等待消息處理返回,而dispatch()又必須等待窗口函數返回),但是SendMessage()發送的WM_try消息會立即被處理,因爲另一個窗口函數同時被調用了。
而且如果f()不能同時執行多次,那麼怎麼會跳出多個messagebox對話框呢?

這是我的理解,希望w_anthony()   和其他高手能指教改正!
 
發表於:2007-06-22 15:59:0237樓 得分:0
我不是書上找出來的,根據實踐推測出來的,比如我上面提的那個例子,運行一遍,等兩次MessageBox出來後,隨便先點哪個的確定都可以,馬上就能看出代碼運行的順序,結果是
2,3
1,4
這說明了什麼,一般人自己都能推測出來了
 
發表於:2007-06-22 16:03:4138樓 得分:0
"第一個對話框變得點擊無效”是因爲DoModal將第一個對話框EnableWindow(FALSE) "這個說法我一直也這麼認爲,但是一直沒有想到怎麼驗證,幸而這裏得到你的確認!

還有一個問題就是我剛纔說的“再彈出另一個對話框b的時候,對話框b又會接替過來消息循環,而把第一個對話框阻塞掉。”,可能有錯誤,因爲第2個彈出對話框b不會使第一個彈出對話框無效,而是使MessageBox()的第一個參數句柄所關聯的對話框無效。
 
發表於:2007-06-22 16:07:5339樓 得分:0
To:摟主sangwf(★小三★)   (   )

你在樓上提的“雖然沒有彈出MessageBox(hWnd1, "主窗口發送WM_try ", " ",0);,但我怎麼能判斷出時AboutBox處理的呢?”我暫時也還沒有想出來怎麼明確證明是AboutBox處理的,畢竟AboutBox是系統封裝好的,無法像主線程那樣修改它的派發消息循環,但大概可以接受這麼個事實,我再想想
 
發表於:2007-06-22 16:10:2740樓 得分:0
樓上二位!
進這貼留個言!
http://community.csdn.net/Expert/topic/5615/5615649.xml?temp=.9416773
 
發表於:2007-06-22 16:12:3741樓 得分:0
進去拿分!
我也學到了這方面的知識!
所以散點分給二位!
呵呵!
 
發表於:2007-06-22 16:18:4442樓 得分:0
程序果然是調出來的,我剛纔試了一下,我舉的例子有個弱智BUG,應該是j   =   ++i,而不是j   =   i++,不然結果就是
1,3
0,4

至於cymvp()上面舉的窗口函數當然是可以被多次調用的,窗口函數是回調函數,他是被消息循環調用的,消息循環本身所在的函數是可能被多次調用的,那它調用的回調函數當然也可以被多次調用了,這不是廢話麼。

另外上面你說的阻塞應該是指代碼的阻塞,窗口的消息正常響應,不會有卡死的現象的……
 
  • sangwf
  • 等 級:
發表於:2007-06-22 16:20:4343樓 得分:0
我剛做了測試,確實是彈出的對話框會接收到父窗口的消息。但問題是,子窗口本身的消息循環並不會處理該消息,應該是傳遞給了父窗口。也就是父窗口一定會收到該消息。而父窗口正在忙於處理彈出的第一個對話框,怎麼會處理接下來的消息呢?
 
發表於:2007-06-22 16:22:2744樓 得分:0
那怎麼解釋在OnTimer()裏面MessageB0x()可以同時跳出來多次呢?不是OnTimer()被同時執行了多次麼?
 
發表於:2007-06-22 16:29:0145樓 得分:0
To:w_anthony()   :  
OK,現在咱們關於窗口函數可以被同時(是同時,也就是可以在同一時刻存在多個函數的副本)調用多次的問題已經達成一致,但是“消息循環本身所在的函數“你指的是dispatchMessage()麼?如果是,那麼我要說:主線程的dispatchMessage()只能同時執行一次!

”指代碼的阻塞,窗口的消息正常響應“消息正常響應咱們也能達成一致,因爲消息響應可以通過對話框的消息循環進行處理;而“代碼的阻塞”我不知道具體指什麼,因爲窗口本身是沒有代碼的。
 
  • sangwf
  • 等 級:
發表於:2007-06-22 16:30:0046樓 得分:0
這個問題還是需要確認一下,對於MFC的消息處理機制,是不是消息隊列中的一條消息執行完之後才能執行下一條?
 
發表於:2007-06-22 16:34:4347樓 得分:0
To:sangwf(★小三★)  

"而父窗口正在忙於處理彈出的第一個對話框,怎麼會處理接下來的消息呢? "你要知道,窗口是不會處理消息的,處理消息的任務是交給窗口函數的,所以只要消息分發循環不會阻塞,那麼消息就都會被正常響應。

 
  • sangwf
  • 等 級:
發表於:2007-06-22 16:35:0748樓 得分:0
彙報一下剛纔我測試的結果,我將主程序的定時器設爲10秒,當第一個時刻到來時,子窗口會不斷的收到父窗口的WM_TIMER消息,這些消息的時間又是不斷加上去的。這是怎麼一回事呢?憑我的理解也該是10秒鐘收到一個的。
 
發表於:2007-06-22 16:42:1949樓 得分:0
To   sangwf(★小三★)   :
這麼說吧父窗口的消息循環所在函數設爲A,彈出的子窗口內部的消息循環部分設爲B
首先程序一直在A處執行循環,彈出子窗口後,程序在B處處於循環狀態,這時B處收到一個給父窗口的消息,B處處理消息時,就會調用父窗口句柄HWND關聯的回調函數,父窗口的回調函數就可以處理掉這個消息了。程序雖然在B處循環,但因爲窗口回調函數這個設計的巧妙之處,使得無論何處的消息循環代碼都可以處理掉所有窗口的消息。

To   cymvp():
我說的f()不會出現執行一半的情況,就是指函數內部沒有消息循環的情況阿,你一個MessageBox()不就循環起來了,這樣當然可能執行一般就來第二次了。
 
  • sangwf
  • 等 級:
發表於:2007-06-22 16:45:5550樓 得分:0
謝謝樓上的,也就是說肯定時單線程處理的,只有在彈出對話框時是特殊情況。
對於正常的消息執行,一定是執行完一個消息才能執行下一條麼?
 
  • sangwf
  • 等 級:
發表於:2007-06-22 16:47:5051樓 得分:0
f()函數肯定是執行完一次才能進入下一次了?
 
發表於:2007-06-22 16:53:1352樓 得分:0
像上面所說的!
如果f()中不彈出摸態對話框的話
那肯定是執行完一次才能進入下一次了
 
  • sangwf
  • 等 級:
發表於:2007-06-22 16:56:1453樓 得分:0
嗯,問題是f()函數在不斷的執行,程序還能接收到消息麼?操作系統會不會把消息緩存起來的?
 
發表於:2007-06-22 16:58:0054樓 得分:0
就是消息機制
 
發表於:2007-06-22 16:59:3855樓 得分:0
沒消息循環或處理的普通函數,肯定是一次一次來,請放心。

有消息隊列保存的,不會丟掉。
 
  • sangwf
  • 等 級:
發表於:2007-06-22 17:01:1256樓 得分:0
是操作系統的消息隊列還是程序本身的消息隊列?
 
發表於:2007-06-22 17:02:3057樓 得分:0
你不用寫代碼保存消息的,操作系統幫你做了。
 
發表於:2007-06-22 17:08:2158樓 得分:0
操作系統會爲你的當前線程維護一個消息隊列!
你可以不用管它!
 
發表於:2007-06-22 17:10:4259樓 得分:0
我有一個問題:OnTimer()是不是同時執行多次?如果是,那麼f()爲什麼不能同時執行多次?
 
發表於:2007-06-22 17:14:1660樓 得分:0
應該是一樣的!
如果如果OnTimer()中不彈出摸態對話框的話
他也是順序執行的
 
發表於:2007-06-22 17:16:1561樓 得分:0
OnTimer()裏面什麼都不寫的話,或沒有處理消息的話,怎麼可能同時執行多次阿?
你自己寫個
CString   str;
for   (int   i   =   0;i <INT_MAX;i++)
{
if   (i%100000==0)
{
str.Format( "%d/r/n ",i);
::OutputDebugString(str);
}
}
看看
 
發表於:2007-06-22 17:18:2062樓 得分:0
所謂“同時”多次執行,說白了,就是一種“變相”的遞歸出現的現象。
 
發表於:2007-06-22 17:18:2663樓 得分:0
好,那看看這段程序,你們說是哪個對話框先彈出,定時器是1秒:

static   int   i   =   0;
static   int   j   =   0;
void   CTimerDlg::OnTimer(UINT   nIDEvent)  
{
i=i+1;

CString   str;
if   (i==2)
{
KillTimer(nIDEvent);
str.Format( "%d,%d/r/n ",j,i);
MessageBox(str);

}
else   if(i==1)
{
Sleep(3000);
str.Format( "%d,%d/r/n ",j,i);
MessageBox(str);
}
CDialog::OnTimer(nIDEvent);
}
 
  • sangwf
  • 等 級:
發表於:2007-06-22 17:18:2664樓 得分:0
也就是操作系統本身沒有一個統一的消息隊列?只是有多個針對每個程序的隊列?

Ontimer執行多次是在彈對話框的時候,如果不彈對話框,只能是順續執行消息了,也就是在一個Ontimer調用執行完之後纔可能執行下一個,不可能出現同時執行多次了。
 
發表於:2007-06-22 17:19:2465樓 得分:0
哈哈!
我們四個人撐起了這個熱貼。。。。
 
發表於:2007-06-22 17:24:5766樓 得分:0
奧,我鑽牛角尖了,我以爲你們說Ontimer不會同時執行多次呢,如果有對話框,那麼Ontimer()就會存在多個執行了一半的情況對吧?
 
  • sangwf
  • 等 級:
發表於:2007-06-22 17:25:1167樓 得分:0
這就奇怪了,我的理解要第二個先彈出的,畢竟整個線程掛起了。第一個不可能出現的,除非沒等第二個彈出,又先處理了第一個的彈出消息,又讓第一個先彈出來了。
 
發表於:2007-06-22 17:26:3568樓 得分:4
現在我把自己總結的說下!
當你在主消息循環的消息處理函數中彈出一個模態對話框!
他阻塞了主消息循環!
然後他自己創建一個消息循環來繼續當前線程的消息處理!
你這時可以把主窗口關閉了!
但是因爲這個彈出的模態對話框還在!它阻塞了winmain這個主消息循環!
所以程序不會退出!
說的應該沒有錯吧!
 
  • sangwf
  • 等 級:
發表於:2007-06-22 17:29:3769樓 得分:0
沒錯,關鍵是winmain沒有獲得焦點,如果獲得了焦點,它的關閉消息會被子窗口處理掉,同樣能夠將其關閉。
 
發表於:2007-06-22 17:33:2870樓 得分:0
sangwf(★小三★)   你做的是第一個先彈出?
 
發表於:2007-06-22 19:28:5971樓 得分:0
To:zhejiang9(Why   not?)
現在我把自己總結的說下!
當你在主消息循環的消息處理函數中彈出一個模態對話框!
他阻塞了主消息循環!
然後他自己創建一個消息循環來繼續當前線程的消息處理!
你這時可以把主窗口關閉了!
但是因爲這個彈出的模態對話框還在!它阻塞了winmain這個主消息循環!
所以程序不會退出!
說的應該沒有錯吧!
==============================================================
有點錯誤,“你這時可以把主窗口關閉了!”這話有問題,主窗口關不掉
另外說一下關於這個Ontimer函數同時調用問題。
第一個WM_TIMER消息,調用Ontimer函數,然後創建一個對話框,同時這個對話框接管消息循環,這時第二個WM_TIMER   來到,由這個對話框來調用Ontimer,又同樣建立一個對話框並接管消息循環。至於函數的執行過程,剛好和這個相反,有點像函數的遞歸 比如下面
A()
{
    static   i=0;
    i++;
    A()//好比彈出Model對話框
    i++;
}
 
發表於:2007-06-22 20:22:4272樓 得分:8
剛上線,cymvp()的例子肯定是下面的先彈出,不過因爲Sleep(3000)的緣故,所以先後很不明顯,基本區分不出來。

To   LS,zhejiang9(Why   not?)總結的很對阿,“你這時可以把主窗口關閉了!”這句話沒有問題,確實可以關閉主對話框,而且程序不會退出的,不信你可以試試關不關的掉。另外LS說的遞歸的理解方式可以說跟我是不謀而合,個人感覺就是一種“變相”的遞歸
 
  • sangwf
  • 等 級:
發表於:2007-06-22 20:50:3473樓 得分:0
恩,遞歸的說法不錯,確實是這麼一回事。但是我的測試是第一個先彈出的,這就理解不明白了。先彈出的one   0,2;後彈出two   0,1。看數據值的話又好像two是先得到的纔對。  
if   (i==2)
{
KillTimer(nIDEvent);
str.Format( "one   %d,%d/r/n ",j,i);
MessageBox(str);

}
else   if(i==1)
{
Sleep(3000);
str.Format( "two   %d,%d/r/n ",j,i);
MessageBox(str);
}
 
發表於:2007-06-22 20:55:3774樓 得分:8
我覺得是這樣,有時候眼睛看到的彈出對話框的順序可能會不太準,建議樓主用斷點跟蹤一下再看一下順序,我也拿不準
 
發表於:2007-06-22 21:20:5175樓 得分:0
static   int   i   =   0;
if   (i >=2)   KillTimer(nIDEvent);
                  i++;
CString   str;
str.Format( "%d ",i);
MessageBox(str);
i++;
                  str.Format( "%d ",i);
MessageBox(str);
CDialog::OnTimer(nIDEvent);
 
  • sangwf
  • 等 級:
發表於:2007-06-23 23:33:5976樓 得分:0
我看不是眼睛的問題,在我的機器上第一個彈出幾秒後,第二個才彈出的,所以還解釋不清。
 
  • sangwf
  • 等 級:
發表於:2007-06-23 23:39:2577樓 得分:0
debug跟蹤了一個,是第二個先彈出的,可能是我代碼裏寫錯了的緣故,寫了兩個:
CDialog::OnTimer(nIDEvent);
CDialog::OnTimer(nIDEvent);

同時,由於兩個是連續彈出的,因爲後彈出的會顯示在最前端,所以one正好是顯示在最前面的。
終於理解清楚了,謝謝以上各位,結貼~
 
發表於:2007-06-24 11:59:0078樓 得分:0
To   w_anthony()  
",“你這時可以把主窗口關閉了!”這句話沒有問題,確實可以關閉主對話框,而且程序不會退出的,不信你可以試試關不關的掉。 "
這個怎麼關啊,當前窗口的焦點在彈出的對話框上,根本無法向主窗口發送WM_CLOSE,怎麼關閉?
 
  • sangwf
  • 等 級:
發表於:2007-06-25 10:50:3979樓 得分:0
我在測試過程中,還真有時可以一不小心把主窗口關掉的,不過概率比較低。
 
發表於:2007-06-25 15:58:4180樓 得分:0
To   red_berries(我再頂頂):

彈出的對話框設一個按鈕或者定時器之類的,將主窗口EnableWindow(TRUE),你不就可以點了……
 
class="replyframe" id="replyframe" name="replyframe" src="http://forum.csdn.net/PointForum/Forum/ReplyTopic.aspx?forumID=f9fb995e-c93d-456a-8097-0b27ccb25c4e&topicID=28c00202-b68a-4fff-8b1e-daa534294c4f&postDate=2007-6-22 12:32:14" frameborder="0" width="100%" scrolling="no" height="490">
<script language="JavaScript" type="text/javascript">/**/</script>

<script src="http://www.google-analytics.com/urchin.js" type="text/javascript"> </script><script type="text/javascript"> _uacct = "UA-2919357-1"; urchinTracker(); </script><script src="http://www.csdn.net/ui/scripts/Csdn/counter.js" type="text/javascript"></script> id="myframe" border="0" name="myframe" src="http://www.csdn.net/ggmm/dd333.htm" frameborder="no" width="0" scrolling="no" height="0">  <script src="/u/ui/scripts/jsframework2.js" type="text/javascript"></script><script src="/u/ui/scripts/System/Plugins/Opera.js" type="text/javascript"></script><script src="/u/ui/scripts/System/Global.js" type="text/javascript"></script><script src="/u/ui/scripts/System/Net/MzJson.js" type="text/javascript"></script><script src="/u/ui/scripts/System/Web/Forms/MzEffect.js" type="text/javascript"></script><script src="/u/ui/scripts/System/Web/Forms/MzBehavior.js" type="text/javascript"></script><script src="/u/ui/scripts/System/Web/Forms/MzForm.js" type="text/javascript"></script><script src="/u/ui/scripts/System/Net/MzCookie.js" type="text/javascript"></script><script src="/u/ui/scripts/Csdn/Forum/UserOnline.js" type="text/javascript"></script><script src="/u/ui/scripts/System/Web/Forms/MzLockWindow.js" type="text/javascript"></script><script src="/u/ui/scripts/System/Web/Forms/MzModalDialog.js" type="text/javascript"></script><script src="/u/ui/scripts/Csdn/Forum/TopicView.js" type="text/javascript"></script> 
網站簡介廣告服務網站地圖幫助聯繫方式誠聘英才English 問題報告
世紀樂知(北京)網絡技術有限公司 版權所有 京 ICP 證 020026 號
Copyright © 2000-2007, CSDN.NET, All Rights Reserved

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章