最近因為突然被發現一個Bug,而發現了一個很奇怪的現象,
那就是,在Domal回傳任何值之前,你把他給砍了,那麼程式就會掛掉了。
這樣好像有點....抽象?
好吧...,那麼請看圖,讓我娓娓道來
首先,我們先創了一個Dialog,並且在上面,我們放上幾個按鈕 (其實重點就是只有那個Create而已)
接下來,我們按下Create
這樣我們就能產生一個能 " 隨時隨便結束的視窗了 "
這句話很重要,真的很重要..。
接下來,我們就將這個Dialog Create出來,並且show出來了。
用這個的好處是什麼 ?
就是你能夠同時操作 這個Main->Create->AboutDialog 這個Dialog,
也能操作下面那個TestAboutDomodal Dialog,
甚至,你也可以幹這件事情也沒關係
又或者你走正常程序
把pointer處理好,不要有memory leak就好。
結論 :
就是兩個Dialog 都是可以操作的,不會互相有咬住的情形出現。
接下來,我們看看DoModal (看了之後你就會知道為什麼我前面要廢話一堆了 )
我們在About裡面,加上兩個按鈕,一個用Create的,一個用DoModal的
跑出來的情況像是這樣,
好了,這時你看看, 你現在只能操做C和D而已,而B和A,基本上你點到死,兩個應該都不會有回應才對。
好,現在問題來了,如果,這時候User想直接關掉A怎麼辦 ?
照正常程序,要關掉A之前,一定要先關掉D,
不信嗎... ,我們來做點實驗你就知道了。
我們在A裡面,設一個Timer,時間到了,我們自動去將A刪掉,在刪之前,我們一樣用正常程序,去Delete B,
然後,B會去看上面有誰,假如有C,就Delete C,假如有D,我也Delete D ,
最後結束。
我們在Timer裡面寫下,10秒後,如果上面有B,我們就要刪掉B
然後,如果有C,我們就砍C,如果有D,我們就砍D
這時候,就會引發錯誤了。
為什麼 ?
我們按重試進來看 Call Stack,看是死在哪裡
是死在這邊,所以才引起一連串的錯誤的。
所以,我們知道了一件事情,
" 在DoModal的時候,User沒有選擇任何一種方式來結束前 ,結束被鎖住的Dialog,會有問題 "
因為,在這邊,他會一直等待回傳值。
好,問題來了,我們知道,要結束A & B & C & D的方式是什麼
A 不用說,就是按X之後→Cancel就好
B由A來砍就可以了 (一樣用delete的方式)
C由B來砍(用Delete的方式)
D (DoModal)呢 ?
D則是要先由User按下任何按鈕 (X = Cancel , OK = IDOK)
等Response那裡收到回傳值,在砍。
那如果檯面上現在有ABCD,那我們又硬要直接結束A,又不想有任何錯誤呢 ?
(就像現在這個實驗一樣)
那麼,我們就必須,走正常程序了 (就是DoModal那邊需要有回傳值)
其實這還蠻簡單的,
只需要用SendMessage的方式就可以了
我們在A的Timer那邊,先去SendMessage給B,問B有沒有DoModal,如果有,我們在SendMessage給D,
告訴D,你要結束了。
接下來,該幹什麼事情就幹什麼事情,
該Delete的去做Delete,這樣在砍的時候,Response那邊就會有IDCANCEL的消息。
然後我就直接在那邊把DoModal的砍掉。
這樣就可以了。
其實這個還蠻好玩的,各位看官不妨動手寫一個這樣的試試看,
這樣的好處,是可以對MFC的生與死,在進一步的了解。
教學到此結束,如果需要source code的,可以在私訊給我,我在寄給你。
留言列表