青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

windows編程非模態對話框

5.4.1非模態對話框的特點

  與模態對話框不同,非模態對話框不壟斷用戶的輸入,用戶打開非模態對話框后,仍然可以與其它界面進行交互。

  非模態對話框的設計與模態對話框基本類似,也包括設計對話框模板和設計CDialog類的派生類兩部分。但是,在對話框的創建和刪除過程中,非模態對話框與模態對話框相比有下列不同之處:

  非模態對話框的模板必須具有Visible風格,否則對話框將不可見,而模態對話框則無需設置該項風格。更保險的辦法是調用CWnd::ShowWindow(SW_SHOW)來顯示對話框,而不管對話框是否具有Visible風格。

  非模態對話框對象是用new操作符在堆中動態創建的,而不是以成員變量的形式嵌入到別的對象中或以局部變量的形式構建在堆棧上。通常應在對話框的擁有者窗口類內聲明一個指向對話框類的指針成員變量,通過該指針可訪問對話框對象。

通過調用CDialog::Create函數來啟動對話框,而不是CDialog::DoModal,這是模態對話框的關鍵所在。由于Create函數 不會啟動新的消息循環,對話框與應用程序共用同一個消息循環,這樣對話框就不會壟斷用戶的輸入。Create在顯示了對話框后就立即返回,而 DoModal是在對話框被關閉后才返回的。眾所周知,在MFC程序中,窗口對象的生存期應長于對應的窗口,也就是說,不能在未關閉屏幕上窗口的情況下先 把對應的窗口對象刪除掉。由于在Create返回后,不能確定對話框是否已關閉,這樣也就無法確定對話框對象的生存期,因此只好在堆中構建對話框對象,而 不能以局部變量的形式來構建之。

  必須調用CWnd::DestroyWindow而不是CDialog::EndDialog來關閉 非模態對話框。調用CWnd::DestroyWindow是直接刪除窗口的一般方法。由于缺省的CDialog::OnOK和CDialog:: OnCancel函數均調用EndDialog,故程序員必須編寫自己的OnOK和OnCancel函數并且在函數中調用DestroyWindow來關 閉對話框。

  因為是用new操作符構建非模態對話框對象,因此必須在對話框關閉后,用delete操作符刪除對話框對象。在屏幕上一個窗口被刪除后,框架會調用CWnd::PostNcDestroy,這是一個虛擬函數,程序可以在該函數中完成刪除窗口對象的工作,具體代碼如下
  void CModelessDialog::PostNcDestroy
  {
      delete 
this;//刪除對象本身
  }
這樣,在刪除屏幕上的對話框后,對話框對象將被自動刪除。擁有者對象就不必顯式的調用delete來刪除對話框對象了。

必須有一個標志表明非模態對話框是否是打開的。這樣做的原因是用戶有可能在打開一個模態對話框的情況下,又一次選擇打開命令。程序根據標志來決定是打開 一個新的對話框,還是僅僅把原來打開的對話框激活。通常可以用擁有者窗口中的指向對話框對象的指針作為這種標志,當對話框關閉時,給該指針賦NULL值, 以表明對話框對象已不存在了。

  提示:在C++編程中,判斷一個位于堆中的對象是否存在的常用方法是判斷指向該對象的指針是否為空。這種機制要求程序員將指向該對象的指針初始化為NULL值,在創建對象時將返回的地址賦給該指針,而在刪除對象時將該指針置成NULL值。

  根據上面的分析,我們很容易把Register程序中的登錄數據對話框改成非模態對話框。這樣做的好處在于如果用戶在輸入數據時發現編輯視圖中有錯誤的數據,那么不必關閉對話框,就可以在編輯視圖中進行修改。

  請讀者按下面幾步操作:

  在登錄數據對話框模板的屬性對話框的MoreStyles頁中選擇Visible項。

  在RegisterView.h頭文件的CRegisterView類的定義中加入
 public:
  CRegisterDialog 
* m_pRegisterDlg;

  在RegisterView.h頭文件的頭部加入對CRegisterDialog類的聲明
  class CRegisterDialog;

加入該行的原因是在CRegisterView類中有一個CRegisterDialog類型的指針,因此必須保證CRegisterDialog類的 聲明出現在CRegisterView之前,否則編譯時將會出錯。解決這個問題有兩種辦法,一種辦法是保證在#include “RegisterView.h”語句之前有#include“RegisterDialog.h”語句,這種辦法造成了一種依賴關系,增加了編譯負擔, 不是很好;另一種辦法是在CRegisterView類的聲明之前加上一個對CRegisterDialog的聲明來暫時“蒙蔽”編譯器,這樣在有 #include“RegisterView.h”語句的模塊中,除非要用到CRegisterDialog類,否則不用加入#include “RegisterDialog.h”語句。

  在RegisterDialog.cpp文件的頭部的#include語句區的末尾添加下面兩行
  #include "RegisterDoc.h"
  #include 
"RegisterView.h"

利用ClassWizard為CRegisterDialog類加入OnCancel和PostNcDestroy成員函數。加入的方法是進入 ClassWizard后選擇MessageMaps頁,并在Classname欄中選擇CRegisterDialog。然后,在ObjectIDs欄 中選擇IDCANCEL后,在Messages欄中雙擊BN_CLICKED,這就創建了OnCancel。要創建PostNcDestroy,先在 ObjectIDs欄中選擇CRegisterDialog,再在Messages欄中雙擊PostNcDestroy即可。

  分別按清單5.10和5.11,對CRegisterView類和CRegisterDialog類進行修改。

  清單5.10CRegisterView類的部分代碼
    CRegisterView::CRegisterView()
    {
        
//TODO:add construction code here
        m_pRegisterDlg=NULL;//指針初始化為NULL
    }

    
void CRegisterView::OnEditRegister()
    {
        
//TODO:Add your command handler code here
        if(m_pRegisterDlg)
            m_pRegisterDlg
->SetActiveWindow();//激活對話框
        else
        {
            
//創建非模態對話框
            m_pRegisterDlg=new CRegisterDialog(this);
            m_pRegisterDlg
->Create(IDD_REGISTER,this);
        }
    }

  清單5.11CRegisterDialog的部分代碼
        void CRegisterDialog::PostNcDestroy()
        {
            
//TODO:Add your specialized code here and/or call the base class
            delete this;//刪除對話框對象
        }

        
void CRegisterDialog::OnCancel()
        {
            
//TODO:Add extra cleanup here
            ((CRegisterView*)m_pParent)->m_pRegisterDlg=NULL;
            DestroyWindow();
//刪除對話框
        }

      CRegisterView::OnEditRegister函數判斷登錄數據對話框是否已打開,若是,就激活對話框,否則,就創建該對話框。該函數中主要調用了下列函數:

  調用CWnd::SetActiveWindow激活對話框,該函數的聲明為
  CWnd* SetActiveWindow();

  該函數使本窗口成為活動窗口,并返回原來活動的窗口。

  調用CDialog::Create來顯示對話框,該函數的聲明為
  BOOL Create(UINTnIDTemplate,CWnd*pParentWnd=NULL);

  參數nIDTemplate是對話框模板的ID。pParentWnd指定了對話框的父窗口或擁有者。

當用戶在登錄數據對話框中點擊“取消”按鈕后,CRegisterDialog::OnCancel將被調用,在該函數中調用CWnd:: DestroyWindow來關閉對話框,并且將CRegisterView的成員m_pRegisterDlg置為NULL以表明對話框被關閉了。調用 DestroyWindow導致了對CRegisterDialog::PostNcDestroy的調用,在該函數中用delete操作符刪除了 CRegisterDialog對象本身。

  編譯并運行Register,現在登錄數據對話框已經變成一個非模態對話框了。

  5.4.2窗口對象的自動清除

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

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

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

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

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

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

  所有標準的Windows控件類。

  從CWnd類直接派生出來的子窗口對象(如用戶定制的控件)。

  切分窗口類CSplitterWnd。

  缺省的控制條類(包括工具條、狀態條和對話條)。

  模態對話框類。

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

  主框架窗口類(直接或間接從CFrameWnd類派生)。

  視圖類(直接或間接從CView類派生)。

  讀者在設計自己的派生窗口類時,可根據窗口對象的創建方法來決定是否將窗口類設計成可以自動清除的。例如,對于一個非模態對話框來說,其對象是創建在堆中的,因此應該具有自動清除功能。

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

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

  提示:在非模態對話框的OnCancel函數中可以不調用CWnd:: DestroyWindow,取而代之的是調用CWnd::ShowWindow(SW_HIDE)來隱藏對話框.在下次打開對話框時就不必調用 Create了,只需調用CWnd::ShowWindow(SW_SHOW)來顯示對話框.這樣做的好處在于對話框中的數據可以保存下來,供以后使用. 由于擁有者窗口在被關閉時會調用DestroyWindow刪除每一個所屬窗口,故只要非模態對話框是自動清除的,程序員就不必擔心對話框對象的刪除問 題. 

posted on 2008-02-18 09:58 FongLuo 閱讀(452) 評論(0)  編輯 收藏 引用

<2025年10月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

導航

常用鏈接

留言簿

隨筆分類(11)

隨筆檔案(79)

文章檔案(1)

收藏夾(38)

學習網站

一般網站

最新隨筆

搜索

積分與排名

最新評論

閱讀排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美在线1区| 欧美成人免费播放| 18成人免费观看视频| 国产精品夜夜夜| 国产精品一二一区| 国产亚洲二区| 伊伊综合在线| a91a精品视频在线观看| 亚洲无线一线二线三线区别av| 亚洲深夜福利网站| 欧美亚洲一区二区在线观看| 久久精品国产第一区二区三区最新章节 | 亚洲黄色一区| 亚洲人成在线播放| 亚洲综合好骚| 久久激情视频| 亚洲国产综合在线| 国产精品99久久不卡二区| 欧美一区二区三区四区在线| 免播放器亚洲| 国产精品日日摸夜夜摸av| 韩日午夜在线资源一区二区| 亚洲欧洲一区二区在线观看| 午夜精品久久久久久久久久久久久 | 羞羞视频在线观看欧美| 久久久久久久综合色一本| 亚洲国产高清视频| 亚洲欧美日韩爽爽影院| 免费久久99精品国产| 国产精品老牛| 99xxxx成人网| 美日韩在线观看| 亚洲一区国产精品| 欧美精品一区二区三区四区| 国产亚洲欧美另类中文| 亚洲图片在线观看| 欧美电影在线| 欧美在线视频导航| 久久婷婷影院| 亚洲免费中文| 欧美网站在线| 一区二区三区色| 亚洲国产精品久久久久秋霞影院| 欧美综合激情网| 国产欧美日韩免费| 亚洲欧美一区二区三区极速播放| 亚洲第一主播视频| 久久久之久亚州精品露出| 国产日韩欧美| 欧美一区二区免费观在线| 99视频国产精品免费观看| 欧美激情一区二区三区在线视频观看 | 亚洲欧美制服中文字幕| 欧美在线免费观看亚洲| 国产日韩欧美精品| 欧美国产一区二区| 国产精品v欧美精品v日韩精品| 久久丁香综合五月国产三级网站| 久久综合九色九九| 欧美一区二区在线免费播放| 免费在线观看一区二区| 欧美在线91| 欧美三级免费| 亚洲福利一区| 国产综合色在线| 一二三四社区欧美黄| 在线观看亚洲a| 亚洲欧美精品在线观看| 在线视频精品一区| 欧美xx视频| 免费成人黄色| 国产一区二区三区直播精品电影| 一本久道久久综合中文字幕| 亚洲第一狼人社区| 久久国产视频网站| 欧美在线一区二区三区| 欧美日韩在线观看一区二区| 亚洲成色精品| 亚洲电影第1页| 久久久久国产精品一区三寸| 亚洲婷婷综合色高清在线| 欧美亚洲在线播放| 欧美视频精品在线| 久久综合网hezyo| 亚洲片在线观看| 黄色资源网久久资源365| 洋洋av久久久久久久一区| 日韩视频久久| 欧美精品999| 欧美 日韩 国产 一区| 一区二区三区在线免费播放| 欧美一区二区三区免费看| 欧美一区二区三区四区在线| 国产精品男人爽免费视频1| 在线一区欧美| 午夜精品视频在线观看一区二区 | 亚洲一区二区av电影| 宅男噜噜噜66一区二区| 欧美另类videos死尸| 亚洲理论在线| 亚洲综合日韩在线| 国产欧美日韩亚洲一区二区三区| 亚洲影院免费| 久久久www成人免费无遮挡大片| 国产精品亚洲综合天堂夜夜| 亚洲欧美精品在线| 亚洲精品欧美精品| 亚洲第一级黄色片| 亚洲精品极品| 美女诱惑一区| 亚洲日本成人在线观看| 蜜桃久久精品乱码一区二区| 国产精品视频久久| 欧美成黄导航| 亚洲国产综合在线| 免费不卡视频| 亚洲乱码国产乱码精品精天堂| 亚洲美女一区| 国产精品久久久久国产a级| 午夜精品影院在线观看| 美女91精品| 日韩一区二区电影网| 国产精品九九| 久久亚洲色图| 亚洲视频免费在线| 开心色5月久久精品| 99天天综合性| 国产一二三精品| 欧美美女日韩| 久久国产精品久久w女人spa| 亚洲动漫精品| 性欧美长视频| 日韩午夜av| 国外视频精品毛片| 欧美日韩一区二区在线播放| 欧美一区二区视频免费观看| 亚洲国产精品一区制服丝袜 | 亚洲国产另类 国产精品国产免费| 日韩图片一区| 国产日韩欧美视频| 欧美精品www| 欧美一区成人| 日韩天堂在线观看| 久久人人九九| 亚洲欧美日韩中文视频| 亚洲国产欧美日韩另类综合| 国产精品美女视频网站| 欧美大香线蕉线伊人久久国产精品| 亚洲男人的天堂在线aⅴ视频| 亚洲激情女人| 免费成人高清视频| 久久久999| 午夜精品一区二区三区在线播放 | 国产亚洲综合精品| 欧美日韩日日夜夜| 免费日韩成人| 欧美在线一二三| 亚洲一区在线播放| 99国产一区二区三精品乱码| 欧美第一黄网免费网站| 久久人人97超碰人人澡爱香蕉| 午夜久久久久| 亚洲欧美视频一区| 亚洲午夜羞羞片| 亚洲最新在线视频| 亚洲精品美女91| 亚洲激情综合| 欧美一级成年大片在线观看| 久久中文精品| 亚洲欧美日韩精品久久| 日韩香蕉视频| 亚洲麻豆av| 99精品国产一区二区青青牛奶| 亚洲第一区在线观看| 影音先锋另类| 欧美a级一区二区| 亚洲人精品午夜| 在线观看免费视频综合| 国产视频久久网| 国产一区二区三区在线观看免费 | 欧美美女福利视频| 欧美日韩午夜剧场| 欧美日韩一区三区四区| 国产精品99免视看9| 国产精品你懂的在线欣赏| 亚洲精品国产系列| 亚洲精品男同| 亚洲午夜在线观看视频在线| 亚洲色诱最新| 亚欧美中日韩视频| 久久精品日产第一区二区三区| 久久精品视频网| 开心色5月久久精品| 欧美激情欧美激情在线五月| 欧美精品一区二区三区视频 | 国产精品一区二区久久| 亚洲午夜在线视频| 先锋影音久久| 一本久久a久久免费精品不卡| 国产日韩欧美综合|