上一個教程中提到了ActiveX的Bug,即如果主窗口直接用變量生成,則關閉窗口時會產生崩潰
如果用new的方式生成,則不會崩潰,所以給出一個臨時的快速解決方案,即主窗口都用new生成,_tWinMain改爲下面這樣:
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow){ CPaintManagerUI::SetInstance(hInstance); HRESULT Hr = ::CoInitialize(NULL); if( FAILED(Hr) ) return 0; CDuiFrameWnd *pFrame = new CDuiFrameWnd; // 這裏必須用new,否則有ActiveX控件時,關閉窗口會產生崩潰 pFrame->Create(NULL, _T("DUIWnd"), UI_WNDSTYLE_FRAME, WS_EX_WINDOWEDGE); pFrame->CenterWindow(); pFrame->ShowModal(); delete pFrame; ::CoUninitialize(); return 0;}
其根本原因是ActiveX控件使用了類似COM的方式,而卻沒有控制好作用域,所以導致析構時,CActiveXCtrl的成員變量m_pViewObject所指向的內存已經無效,因此產生了崩潰。之所以用new的方式不會崩潰,是因爲new出來的內存,即使對象析構後,其內存還是有效的。
由於其使用了類似COM的行爲,有幾處delete this,而Alberl並不瞭解微軟自己的COM和ActiveX內部是怎麼處理的,所以也就無法評價duilib的COM和ActiveX,當然啦,Alberl還是調試了一下,發現 ActiveXUI.cpp裏面的那幾個類都是模擬了COM的方式,採用了引用計數,但是那幾個類的Release順序貌似有點亂,而且那幾個類互相包含,所以才造成析構時的那些問題,由於Alberl目前的重心是寫入門教程,加之水平有限,所以不能短時間從根本上解決這個問題,就坐等大神啦~~~