1. 程式人生 > >MFC做控制元件弄得我苦不堪言!(我親身經歷的問題及解決辦法)

MFC做控制元件弄得我苦不堪言!(我親身經歷的問題及解決辦法)

        由於我沒有系統的學過ATL,而公司做控制元件的地方又很多,為了保險起見,我還是選擇了使用MFC來做控制元件,在這過程中我發現了MFC的好多奇怪的問題,在這裡列出來,大家可以討論一下。

        一:MFC不能做WEB服務端控制元件
        這個我是聽一老外說的,我具體試了一下,在ASP中用CreateObject的時候,的確失敗,不知道大家有沒有用MFC成功做過WEB服務端控制元件的呢?

        二:如果控制元件中有執行緒未結束,則在關閉IE的時候有問題
        我的除錯條件是,在CXXXXCtrl類中開啟一個無模式對話方塊,在無模式對話方塊中開啟一個工作執行緒,如果在CXXXXCtrl類中開啟一個工作執行緒,問題是不是這樣我就不能肯定了。
        假如控制元件退出的時候,不結束工作執行緒的話,那麼當控制元件在IE中執行的時候,它會把控制元件所在的IE視窗和上一個IE視窗一塊兒關閉,但不報任何錯誤。按道理上,主執行緒結束,將會導致子執行緒結束,所以結不結束工作執行緒,效果應該是一樣的,但結果卻不一樣。
        注:工作執行緒中沒有任何需要釋放的資源。

        三:關於在控制元件中開無模式對話方塊
        這個問題花去了我一週的除錯時間,問題是這樣的:
我想在控制元件中開個無模式對話方塊好多人都做過,也不會有什麼問題,可是,如果在無模式對話方塊中再開一個無模式對話方塊呢?為了說明問題方便,我把在CXXXXCtrl類中開啟的無模式對話方塊稱為Dialog1(Child屬性),在Dialog1中開啟的無模式對話方塊稱為Dialog2(Popup屬性),大家可以想像成Dialog2為一查詢對話方塊。為了讓問題表現出來,我們在Dialog2上做點手腳:
        在Dialog2上放個Edit框,並關聯一個CEdit型控制變數,完了後編譯控制元件,然後將控制元件放到IE中執行,在關閉IE的時候,問題出來了,一堆非法操作,什麼什麼地址不能讀等錯誤,大家可以試試。奇怪的是在Dialgo2上放個列表框,並關聯CListCtrl類控制變數卻沒有問題。
        這個問題總結起來就是,在Dialog1中建立Dialog2的時候,無法讓Dialog1成為Dialog2的父視窗,於是在資源釋放問題上造成錯亂,試著用SetParent函式給Dialog2指定父視窗為Dialog1也不行。
        解決辦法:在Dialog1的OnDestroy函式中執行Dialog2.DestroyWindow();
        如果在Dialog2中開啟無模式對話方塊Dialog3,恐怕就更復雜了,我都沒除錯過。

        四:在控制元件中使用另一自編寫的控制元件,呼叫IsDialogMessage函式造成死迴圈
        我的除錯條件是,在CXXXXCtrl類中開啟一個無模式對話方塊,在無模式對話方塊中放上一個自寫的MFC控制元件,
併為其關聯控制型變數。假定無模式對話方塊為pDialog1(Child屬性),在CXXXXCtrl類的PreTranslateMessage函式中寫上如下程式碼:
return ::IsWindow(pDialog1->m_hWnd) && pDialog1->IsDialogMessage(pMsg) || COleControl::PreTranslateMessage(pMsg);
        結果會怎麼樣呢?請這樣除錯:
        在IE中執行控制元件,完全遠行起來後,最小化IE,再還原IE,此時隨便按鍵盤上某一個鍵,則CPU使用佔百分之百,只能強行關閉IE這個問題我除錯了好久,最後發現是pDialog1->IsDialogMessage(pMsg)呼叫進入了死迴圈!這個問題的解決辦法你想都想不到,如下:
        把pDialog1->IsDialogMessage(pMsg)改成::IsDialogMessage(pDialog1->m_hWnd, pMsg)即可。
pDialog1->IsDialogMessage(pMsg)和::IsDialogMessage(pDialog1->m_hWnd, pMsg)據說效果是一樣的,我也認為一樣,可是實際上,他們並不一樣,這個問題怎麼產生的我到現在還不明白!

        注:我上面提到在無模式對話方塊上放置一個自寫的MFC控制元件,雖然這個控制元件是我寫的,但我可以保證這個控制元件不會有問題,我的自信來自下面的事實:
        用VC6.0嚮導完全按預設生成一個MFC控制元件,不寫任何一行程式即編譯程式,然後用這個控制元件來做實驗,效果一樣!當然,如果不放置自寫的MFC控制元件,上面的問題不會發生,這個我是除錯過的。

        注:上面的問題,除了第一個,其它的在應用程式中(比如新增到對話方塊上而不是在IE中)使用則完全沒有問題。