⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chap5_4.htm

📁 vc教程,真正的程序员用Visual C++。如果你想当程序员
💻 HTM
📖 第 1 页 / 共 2 页
字号:
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">else</span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">{</span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">//创建非模态对话框</span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">m_pRegisterDlg=new CRegisterDialog(this);</span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">m_pRegisterDlg-&gt;Create(IDD_REGISTER,this);</span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">}</span></b></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">}<br>
    </span></p>
    <p><b><span style="font-size: 9pt"> </span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt"> </span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">清单5.11 CRegisterDialog的部分代码</span></b></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">void CRegisterDialog::PostNcDestroy() </span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">{</span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">// TODO: Add your specialized code here 
    and/or call the base class</span></p>
    <p><b><span style="font-size: 9pt"> </span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">delete this; //删除对话框对象</span></b></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">}</span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt"> </span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">void CRegisterDialog::OnCancel() </span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">{</span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">// TODO: Add extra cleanup here</span></p>
    <p><b><span style="font-size: 9pt"> </span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">((CRegisterView*)m_pParent)-&gt;m_pRegisterDlg=NULL;</span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">DestroyWindow(); //删除对话框 </span></b></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">}</span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">CRegisterView::OnEditRegister函数判断登录数据对话框是否已打开,若是,就激活对话框,否则,就创建该对话框。该函数中主要调用了下列函数:</span></p>
    <blockquote>
      <blockquote>
        <p ALIGN="JUSTIFY"><span style="font-size: 9pt">调用CWnd::SetActiveWindow激活对话框,该函数的声明为<br>
        CWnd* SetActiveWindow( );<br>
        该函数使本窗口成为活动窗口,并返回原来活动的窗口。</span></p>
        <p ALIGN="JUSTIFY"><span style="font-size: 9pt">调用CDialog::Create来显示对话框,该函数的声明为<br>
        BOOL Create( UINT nIDTemplate, CWnd* pParentWnd = NULL );<br>
        参数nIDTemplate是对话框模板的ID。pParentWnd指定了对话框的父窗口或拥有者。</span></p>
      </blockquote>
    </blockquote>
    <p><span style="font-size: 9pt"> </span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">当用户在登录数据对话框中点击“取消”按钮后,CRegisterDialog::OnCancel将被调用,在该函数中调用CWnd::DestroyWindow来关闭对话框,并且将CRegisterView的成员m_pRegisterDlg置为NULL以表明对话框被关闭了。调用DestroyWindow导致了对CRegisterDialog::PostNcDestroy的调用,在该函数中用delete操作符删除了CRegisterDialog对象本身。</span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">编译并运行Register,现在登录数据对话框已经变成一个非模态对话框了。</span></p>
    <b><p ALIGN="JUSTIFY"></b><span style="font-size: 9pt"><font color="#3973DE">5.4.2 
    窗口对象的自动清除</font></span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">一个MFC窗口对象包括两方面的内容:一是窗口对象封装的窗口,即存放在m_hWnd成员中的HWND(窗口句柄),二是窗口对象本身是一个C++对象。要删除一个MFC窗口对象,应该先删除窗口对象封装的窗口,然后删除窗口对象本身。</span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">删除窗口最直接方法是调用CWnd::DestroyWindow或::DestroyWindow,前者封装了后者的功能。前者不仅会调用后者,而且会使成员m_hWnd保存的HWND无效(NULL)。如果DestroyWindow删除的是一个父窗口或拥有者窗口,则该函数会先自动删除所有的子窗口或被拥有者,然后再删除父窗口或拥有者。在一般情况下,在程序中不必直接调用DestroyWindow来删除窗口,因为MFC会自动调用DestroyWindow来删除窗口。例如,当用户退出应用程序时,会产生WM_CLOSE消息,该消息会导致MFC自动调用CWnd::DestroyWindow来删除主框架窗口,当用户在对话框内按了OK或Cancel按钮时,MFC会自动调用CWnd::DestroyWindow来删除对话框及其控件。</span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">窗口对象本身的删除则根据对象创建方式的不同,分为两种情况。在MFC编程中,会使用大量的窗口对象,有些窗口对象以变量的形式嵌入在别的对象内或以局部变量的形式创建在堆栈上,有些则用new操作符创建在堆中。对于一个以变量形式创建的窗口对象,程序员不必关心它的删除问题,因为该对象的生命期总是有限的,若该对象是某个对象的成员变量,它会随着父对象的消失而消失,若该对象是一个局部变量,那么它会在函数返回时被清除。</span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">对于一个在堆中动态创建的窗口对象,其生命期却是任意长的。初学者在学习C++编程时,对new操作符的使用往往不太踏实,因为用new在堆中创建对象,就不能忘记用delete删除对象。读者在学习MFC的例程时,可能会产生这样的疑问,为什么有些程序用new创建了一个窗口对象,却未显式的用delete来删除它呢?问题的答案就是有些MFC窗口对象具有自动清除的功能。</span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">如前面讲述非模态对话框时所提到的,当调用CWnd::DestroyWindow或::DestroyWindow删除一个窗口时,被删除窗口的PostNcDestroy成员函数会被调用。缺省的PostNcDestroy什么也不干,但有些MFC窗口类会覆盖该函数并在新版本的PostNcDestroy中调用delete 
    this来删除对象,从而具有了自动清除的功能。此类窗口对象通常是用new操作符创建在堆中的,但程序员不必操心用delete操作符去删除它们,因为一旦调用DestroyWindow删除窗口,对应的窗口对象也会紧接着被删除。</span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">不具有自动清除功能的窗口类如下所示。这些窗口对象通常是以变量的形式创建的,无需自动清除功能。</span></p>
    <blockquote>
      <blockquote>
        <p ALIGN="JUSTIFY"><span style="font-size: 9pt">所有标准的Windows控件类。</span></p>
        <p ALIGN="JUSTIFY"><span style="font-size: 9pt">从CWnd类直接派生出来的子窗口对象(如用户定制的控件)。</span></p>
        <p ALIGN="JUSTIFY"><span style="font-size: 9pt">切分窗口类CSplitterWnd。</span></p>
        <p ALIGN="JUSTIFY"><span style="font-size: 9pt">缺省的控制条类(包括工具条、状态条和对话条)。</span></p>
        <p ALIGN="JUSTIFY"><span style="font-size: 9pt">模态对话框类。</span></p>
      </blockquote>
    </blockquote>
    <p><span style="font-size: 9pt"> </span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">具有自动清除功能的窗口类如下所示,这些窗口对象通常是在堆中创建的。</span></p>
    <blockquote>
      <blockquote>
        <p ALIGN="JUSTIFY"><span style="font-size: 9pt">主框架窗口类(直接或间接从CFrameWnd类派生)。</span></p>
        <p ALIGN="JUSTIFY"><span style="font-size: 9pt">视图类(直接或间接从CView类派生)。</span></p>
      </blockquote>
    </blockquote>
    <p><span style="font-size: 9pt"> </span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">读者在设计自己的派生窗口类时,可根据窗口对象的创建方法来决定是否将窗口类设计成可以自动清除的。例如,对于一个非模态对话框来说,其对象是创建在堆中的,因此应该具有自动清除功能。</span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">综上所述,对于MFC窗口类及其派生类来说,在程序中一般不必显式删除窗口对象。也就是说,既不必调用DestroyWindow来删除窗口对象封装的窗口,也不必显式地用delete操作符来删除窗口对象本身。只要保证非自动清除的窗口对象是以变量的形式创建的,自动清除的窗口对象是在堆中创建的,MFC的运行机制就可以保证窗口对象的彻底删除。</span></p>
    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">如果需要手工删除窗口对象,则应该先调用相应的函数(如CWnd::DestroyWindow)删除窗口,然后再删除窗口对象.对于以变量形式创建的窗口对象,窗口对象的删除是框架自动完成的.对于在堆中动态创建了的非自动清除的窗口对象,必须在窗口被删除后,显式地调用delete来删除对象(一般在拥有者或父窗口的析构函数中进行).对于具有自动清除功能的窗口对象,只需调用CWnd::DestroyWindow即可删除窗口和窗口对象。注意,对于在堆中创建的窗口对象,不要在窗口还未关闭的情况下就用delete操作符来删除窗口对象.</span></p>
    <b><div align="center"><center><table border="2" cellpadding="2" cellspacing="0"
    width="90%" bgcolor="#A3BDEF">
      <tr>
        <td width="100%"></b><span style="font-size: 9pt">提示:在非模态对话框的OnCancel函数中可以不调用CWnd::DestroyWindow,取而代之的是调用CWnd::ShowWindow(SW_HIDE)来隐藏对话框.在下次打开对话框时就不必调用Create了,只需调用CWnd::ShowWindow(SW_SHOW)来显示对话框.这样做的好处在于对话框中的数据可以保存下来,供以后使用.由于拥有者窗口在被关闭时会调用DestroyWindow删除每一个所属窗口,故只要非模态对话框是自动清除的,程序员就不必担心对话框对象的删除问题.</span></td>
      </tr>
    </table>
    </center></div><p ALIGN="JUSTIFY"><span style="font-size: 9pt"> </span></p>
    <div align="center"><center><table border="0" cellpadding="0" cellspacing="0" width="615">
      <tr>
        <td><span style="font-size: 9pt"><a href="chap5_3.htm">上一页</a></span></td>
        <td><p align="right"><span style="font-size: 9pt"><a href="chap5_5.htm">下一页</a></span></td>
      </tr>
    </table>
    </center></div><font SIZE="5"><hr noshade color="#3973DE" size="1">
    <p align="center"></font><font size="2" color="#000000">本教程由<a
    href="http://vcdynasty.yeah.net">Visual C++王朝(Where programmers come together)</a>协助制作<br>
    未经许可,请勿以任何形式复制</font></td>
    <b>
  </tr>
</table>
</center></div></b>
</body>
</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -