作者Keitaro (動き出す時間...)
看板C_and_CPP
標題[問題] 請問MFC create dialog的問題
時間Fri Aug 15 00:21:55 2014
開發平台(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