看板 C_and_CPP 關於我們 聯絡資訊
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) VC2008 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) None 問題(Question): MFC create dialog出問題,請看底下說明 補充說明(Supplement): 版上各位好,不才小弟又上來請教一個MFC的問題。 今天在工作時,碰到了一個怪現象,還請各位指教。 因為工作的關係我不能把所有的程式碼都貼上來,只能把出問題的地方概述一下。 我在一個dialog裡面的一個按鈕寫的功能是這樣的 "當按鈕被按下時,建立一個新的dialog,從server下載檔案,dialog要顯示下載進度" 原本我直接在觸發事件的OnLButtonDown寫這樣 void DialogB::OnLButtonDown() { pA = new DialogA(); pA->Create(ID_A); pA->ShowWindow(SW_SHOW); } pA這個位址被宣告在DialogB裡面 class DialogB : public CDialog { DialogB(); ~DialogB(); DialogA* pA; } 後來考慮到user如果按了好幾次,那麼pA就會一直new dialog, 之前被new出來的dialog沒有delete,造成memory leak。 所以我把new的兩行動作放到DialogB的建構式裡面去做。 如下所示 DialogB::DialogB() { pA = new DialogA(); pA->Create(ID_A); pA->ShowWindow(SW_HIDE) } void DialogB::OnLButtonDown() { pA->ShowWindow(SW_SHOW) } 程式跑起來卻crash,發現原因是pA這個dialog上面顯示的一些文字的handle為NULL。 這些文字可能拿來顯示下載的進度、傳輸速度之類的。 我用debug mode去看,發現當程式執行到 pA->Create(ID_A); 這一行時,跳到CDialog的OnInitDialog bool DialogA::OnInitDialog() { CDialog::OnInitDialog(); ......//底下是其他顯示文字、動畫的檢查跟設定 return true; } 我在debug mode底下看到,當程式執行完 CDialog::OnInitDialog(); 這一行時,this指標底下所有元件handle全部都建立起來了。 然後一直跑到最底下的右刮號"}", 我看到this指標底下所有元件的handle都還是存在的,並非NULL。 問題來了,跑完OnInitDialog,按F5使得程式停在 pA->ShowWindow(SW_HIDE) 我看到pA所有的元件的handle全都變成0了。 我確定在離開OnInitDialog最後一行,handle都有數值的。 但windows初始化完dialog回到原本create pA的建構式, 中間的程式碼,windows做了什麼,看不到,也無從得知。 有沒有什麼可能原因,是再離開OnInitDialog後,所有元件的handle又被清除的? 另一個線索是,我測試把OnInitDialog底下所有的東西,全部拿出來, 放到另一個function裡面,改成這樣 bool DialogA::OnInitDialog() { CDialog::OnInitDialog(); return true; } void DialogA::Test() { ......//原本放在OnInitDialog裡面要做的事 } 然後DialogB的建構式改為這樣 DialogB::DialogB() { pA = new DialogA(); pA->Create(ID_A); pA->Test(); pA->ShowWindow(SW_HIDE) } 神奇,改成這樣handle就不會被清掉了! 請教版上各位先進,原本的寫法,有可能發生了什麼事, 讓windows把我建好的handle給清掉了? 謝謝! -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 114.37.153.215 ※ 文章網址: http://www.ptt.cc/bbs/C_and_CPP/M.1408033317.A.453.html ※ 編輯: Keitaro (114.37.153.215), 08/15/2014 00:22:50
TeaEEE: 你的dialogB是modal還是modaless 08/15 02:18
Keitaro: 兩個都是new出來的,modelless 08/15 02:25
TeaEEE: 如果都是modaless,你把dialogB中new A的動作移到B的OnIni 08/15 11:10
TeaEEE: OnInitDialog 08/15 11:10