乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      MFC窗口銷毀過程...

       GideonHuang 2009-11-13

      MFC窗口銷毀過程 點擊即可復(fù)制標(biāo)題和URL 復(fù)制鏈接

      考慮單窗口情況:

        假設(shè)自己通過new創(chuàng)建了一個窗口對象pWnd,然后pWnd->Create。則銷毀窗口的調(diào)用次序:

        1. 手工調(diào)用pWnd->DestroyWindow();
        2. DestroyWindow會發(fā)送WM_DESTROY;
        3. WM_DESTROY對應(yīng)的消息處理函數(shù)是OnDestroy();
        4. DestroyWindow會發(fā)送WM_NCDESTROY;
        5. WM_NCDESTROY對應(yīng)的消息處理函數(shù)是OnNcDestroy;
        6. OnNcDestroy最后會調(diào)用PostNcDestroy;
        7. PostNcDestroy經(jīng)常被用戶重載以提供釋放內(nèi)存操作。例如可以使用delete this;

        通過這種方式,窗口對象對應(yīng)的窗口和窗口對象本身都被釋放了。

      含有子窗口的情況

        如果含有子窗口,則調(diào)用父窗口的DestroyWindow時,它會向子窗口發(fā)送WM_DESTROY和WM_NCDESTROY消息。

        具體調(diào)用順序參考下文的例子。

        DestroyWindowdelete的影響:

        應(yīng)該說前者對后者并沒有什么影響。但經(jīng)常在DestroyWindow間接導(dǎo)致執(zhí)行的PostNcDestroy中delete窗口對象指針,即delete this。

        CView::PostNcDestroy中唯一的操作就是delete this;CframeWnd::PostNcDestory也是如此。而默認(rèn)的CWnd::PostNcDestroy是空操作,CDialog中也沒有對其進行重載,即也是空。

        deleteDestroy的影響:

        delete會導(dǎo)致析構(gòu)函數(shù)。CWnd的析構(gòu)函數(shù)中有對DestroyWindow的調(diào)用,但必須保證:

        m_hWnd != NULL &&

        this != (CWnd*) &wndTop &&this != (CWnd*)&wndBottom &&

        this != (CWnd*)&wndTopMost &&this != (CWnd*)&wndNoTopMost。

        Cdialog的析構(gòu)函數(shù)中也有對DestroyWindow的調(diào)用,但條件比較松,只需要m_hWnd != NULL。另外Cdialog::DoModal也會調(diào)用DestroyWindow。

        CFrameWnd的OnClose中會調(diào)用DestroyWindow,但其析構(gòu)中不會調(diào)用DestroyWindow。

        CView的析構(gòu)也不會調(diào)用DestroyWindow。

        一個SDI程序的銷毀過程

        有CMainFrame類、CMyView類。并且CMyView有兩個子窗口CMyDlg和CmyWnd的實例。

        點擊退出按鈕,CMainFrame會收到WM_CLOSE消息。CframeWnd(CMainFrame的父類)間接會調(diào)用CWnd::DestroyWindow;它首先向CMyView發(fā)送WM_DESTORY和WM_NCDESTROY消息,并引發(fā)相應(yīng)的處理函數(shù);然后向CMyDlg發(fā)送WM_DESTORY和WM_NCDESTROY消息,并引發(fā)相應(yīng)的處理函數(shù);然后向CMyWnd發(fā)送WM_DESTORY和WM_NCDESTROY消息,并引發(fā)相應(yīng)的處理函數(shù)。

        具體的執(zhí)行順序是:

        1. 調(diào)用CMainFrame::DestroyWindow
        2. CFrameWnd::OnDestroy
        3. CMyView::OnDestroy
        4. CmyWnd::OnDestroy
        5. CmyDlg::OnDestroy
        6. CmyWnd::PostNcDestroy
        7. CmyWnd的析構(gòu)
        8. CmyDlg::OnDestroy
        9. CmyDlg的析構(gòu)
        10. CMyView::PostNcDestroy
        11. CmyView的析構(gòu)
        12. CMainFrame的析構(gòu)
        13. CMainFrame::DestroyWindow退出

        上面情況是假設(shè)我們在CmyWnd和CmyDlg的PostNcDestroy中添加了delete this。如果沒有添加,則7,10不會執(zhí)行。

        因為CView::PostNcDestroy中調(diào)用了delete this,所以然后會執(zhí)行CMyView的析構(gòu)操作。因為CframeWnd::PostNcDestroy中調(diào)用了delete this,所以最后執(zhí)行CMainFrame的析構(gòu)操作。

        如果自己的CmyDlg和CmyWnd在PostNcDestroy中有delete this;則二者會被析構(gòu)。否則內(nèi)存泄漏。當(dāng)然delete也可以放在CMyView的析構(gòu)中做,只是不夠OO。

        總結(jié)

        可以有兩種方法銷毀窗口對象對應(yīng)的窗口和釋放窗口對象指針。一種是通過DestroyWindow。這是比較好的方法,因為最后MFC會自動相應(yīng)WM_CLOSE導(dǎo)致CframWnd::DestroyWindow被調(diào)用,然后會一次釋放所有子窗口的句柄。用戶需要做的是在PostNcDestroy中釋放堆窗口對象指針。但因為某些對象是在棧中申請的,所以delete this可能出錯。這就要保證寫程序時自己創(chuàng)建的窗口盡量使用堆申請。

        另一種是delete。Delete一個窗口對象指針有的窗口類(如CWnd,Cdialog)會間接調(diào)用DestroyWindow,有的窗口類(如CView,CframeWn)不會調(diào)用DestroyWindow。所以要小心應(yīng)對。

        二者是相互調(diào)用的,很繁瑣。

        一個MFC窗口對象包括兩方面的內(nèi)容:一是窗口對象封裝的窗口,即存放在m_hWnd成員中的HWND(窗口句柄),二是窗口對象本身是一個C++對象。要刪除一個MFC窗口對象,應(yīng)該先刪除窗口對象封裝的窗口,然后刪除窗口對象本身。

        刪除窗口最直接方法是調(diào)用CWnd::DestroyWindow或::DestroyWindow,前者封裝了后者的功能。前者不僅會調(diào)用后者,而且會使成員m_hWnd保存的HWND無效(NULL)。如果DestroyWindow刪除的是一個父窗口或擁有者窗口,則該函數(shù)會先自動刪除所有的子窗口或被擁有者,然后再刪除父窗口或擁有者。在一般情況下,在程序中不必直接調(diào)用DestroyWindow來刪除窗口,因為MFC會自動調(diào)用DestroyWindow來刪除窗口。例如,當(dāng)用戶退出應(yīng)用程序時,會產(chǎn)生WM_CLOSE消息,該消息會導(dǎo)致MFC自動調(diào)用CWnd::DestroyWindow來刪除主框架窗口,當(dāng)用戶在對話框內(nèi)按了OK或Cancel按鈕時,MFC會自動調(diào)用CWnd::DestroyWindow來刪除對話框及其控件。

        窗口對象本身的刪除則根據(jù)對象創(chuàng)建方式的不同,分為兩種情況。在MFC編程中,會使用大量的窗口對象,有些窗口對象以變量的形式嵌入在別的對象內(nèi)或以局部變量的形式創(chuàng)建在堆棧上,有些則用new操作符創(chuàng)建在堆中。對于一個以變量形式創(chuàng)建的窗口對象,程序員不必關(guān)心它的刪除問題,因為該對象的生命期總是有限的,若該對象是某個對象的成員變量,它會隨著父對象的消失而消失,若該對象是一個局部變量,那么它會在函數(shù)返回時被清除。

        對于一個在堆中動態(tài)創(chuàng)建的窗口對象,其生命期卻是任意長的。初學(xué)者在學(xué)習(xí)C++編程時,對new操作符的使用往往不太踏實,因為用new在堆中創(chuàng)建對象,就不能忘記用delete刪除對象。讀者在學(xué)習(xí)MFC的例程時,可能會產(chǎn)生這樣的疑問,為什么有些程序用new創(chuàng)建了一個窗口對象,卻未顯式的用delete來刪除它呢?問題的答案就是有些MFC窗口對象具有自動清除的功能。

        如前面講述非模態(tài)對話框時所提到的,當(dāng)調(diào)用CWnd::DestroyWindow或::DestroyWindow刪除一個窗口時,被刪除窗口的PostNcDestroy成員函數(shù)會被調(diào)用。缺省的PostNcDestroy什么也不干,但有些MFC窗口類會覆蓋該函數(shù)并在新版本的PostNcDestroy中調(diào)用delete this來刪除對象,從而具有了自動清除的功能。此類窗口對象通常是用new操作符創(chuàng)建在堆中的,但程序員不必操心用delete操作符去刪除它們,因為一旦調(diào)用DestroyWindow刪除窗口,對應(yīng)的窗口對象也會緊接著被刪除。

        不具有自動清除功能的窗口類如下所示。這些窗口對象通常是以變量的形式創(chuàng)建的,無需自動清除功能。

        所有標(biāo)準(zhǔn)的Windows控件類。

        1. 從CWnd類直接派生出來的子窗口對象(如用戶定制的控件)。
        2. 切分窗口類CSplitterWnd。
        3. 缺省的控制條類(包括工具條、狀態(tài)條和對話條)。
        4. 模態(tài)對話框類。   

        具有自動清除功能的窗口類如下所示,這些窗口對象通常是在堆中創(chuàng)建的。

        1. 主框架窗口類(直接或間接從CFrameWnd類派生)。
        2. 視圖類(直接或間接從CView類派生)。 

          在設(shè)計自己的派生窗口類時,可根據(jù)窗口對象的創(chuàng)建方法來決定是否將窗口類設(shè)計成可以自動清除的。例如,對于一個非模態(tài)對話框來說,其對象是創(chuàng)建在堆中的,因此應(yīng)該具有自動清除功能。

        綜上所述,對于MFC窗口類及其派生類來說,在程序中一般不必顯式刪除窗口對象。也就是說,既不必調(diào)用DestroyWindow來刪除窗口對象封裝的窗口,也不必顯式地用delete操作符來刪除窗口對象本身。只要保證非自動清除的窗口對象是以變量的形式創(chuàng)建的,自動清除的窗口對象是在堆中創(chuàng)建的,MFC的運行機制就可以保證窗口對象的徹底刪除。

        如果需要手工刪除窗口對象,則應(yīng)該先調(diào)用相應(yīng)的函數(shù)(如CWnd::DestroyWindow)刪除窗口,然后再刪除窗口對象.對于以變量形式創(chuàng)建的窗口對象,窗口對象的刪除是框架自動完成的.對于在堆中動態(tài)創(chuàng)建了的非自動清除的窗口對象,必須在窗口被刪除后,顯式地調(diào)用delete來刪除對象(一般在擁有者或父窗口的析構(gòu)函數(shù)中進行).對于具有自動清除功能的窗口對象,只需調(diào)用CWnd::DestroyWindow即可刪除窗口和窗口對象。注意,對于在堆中創(chuàng)建的窗口對象,不要在窗口還未關(guān)閉的情況下就用delete操作符來刪除窗口對象.

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多