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

📄 chap5_5.htm

📁 网络资源
💻 HTM
📖 第 1 页 / 共 4 页
字号:
<html>

<head>
<title>5.5 标签式对话框</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 3.0">
</head>

<body link="#3973DE" alink="#3973DE">
<font SIZE="5"><b><div align="center"><center>

<table border="0" width="615" cellspacing="0" cellpadding="0">
  <tr>
    </b><td><div align="center"><center><table border="0" width="615" cellpadding="0" cellspacing="0" height="20">
      <tr>
        <td width="377" bgcolor="#15397D" height="20"></td>
        <td width="238" bgcolor="#000000" height="20"><p align="right"></font><span style="text-decoration: none"><a href="../../index.htm"><font color="#FFFFFF">电脑报Visual 
        C++网络教程</font></a></span></td>
      </tr>
    </table>
    </center></div><font FACE="Times New Roman" SIZE="3"><b><p ALIGN="CENTER"></b></font><font color="#3973DE" FACE="Times New Roman" size="4">5.5 </font><font color="#3973DE" size="4">标签式对话框</font><font FACE="Times New Roman" size="4"></p>
    <p ALIGN="JUSTIFY"></font><font SIZE="3">在设计较为复杂的对话框时,常常会遇到这种情况:对某一事物的设置或选项需要用到大量的控件,以至于一个对话框放不下,而这些控件描述的是类似的属性,不能分开。用普通的对话框技术,这一问题很难解决。</font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY">MFC</font><font SIZE="3">提供了对标签式对话框的支持,可以很好的解决上述问题。标签式对话框实际上是一个包含了多个子对话框的对话框,这些子对话框通常被称为页</font><font FACE="Times New Roman" SIZE="3">(Page)</font><font SIZE="3">。每次只有一个页是可见的,在对话框的顶端有一行标签,用户通过单击这些标签可切换到不同的页。显然,标签式对话框可以容纳大量的控件。在象</font><font FACE="Times New Roman" SIZE="3">Word</font><font SIZE="3">和</font><font FACE="Times New Roman" SIZE="3">Developer Studio</font><font SIZE="3">这样复杂的软件中,用户会接触到较多的标签式对话框,一个典型的标签式对话框如图</font><font FACE="Times New Roman" SIZE="3">5.10</font><font SIZE="3">所示。</font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="center"></font><font SIZE="3"><img src="T5_10.gif" alt="T5_10.tif (119141 bytes)" WIDTH="447" HEIGHT="247"></font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="center"></font><font size="2">图<font FACE="Times New Roman">5.10 </font>典型的标签式对话框<font FACE="Times New Roman"></p>
    </font></font><font FACE="Times New Roman" SIZE="3"><b><p ALIGN="JUSTIFY"></b></font><font color="#3973DE" FACE="Times New Roman" SIZE="3">5.5.1 </font><font SIZE="3" color="#3973DE">标签式对话框的创建</font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY"></font><font SIZE="3">为了支持标签式对话框,</font><font FACE="Times New Roman" SIZE="3">MFC</font><font SIZE="3">提供了</font><font FACE="Times New Roman" SIZE="3">CPropertySheet</font><font SIZE="3">类和</font><font FACE="Times New Roman" SIZE="3">CPropertyPage</font><font SIZE="3">类。前者代表对话框的框架,后者代表对话框中的某一页。</font><font FACE="Times New Roman" SIZE="3">CPropertyPage</font><font SIZE="3">是</font><font FACE="Times New Roman" SIZE="3">CDialog</font><font SIZE="3">类的派生类,而</font><font FACE="Times New Roman" SIZE="3">CPropertySheet</font><font SIZE="3">是</font><font FACE="Times New Roman" SIZE="3">CWnd</font><font SIZE="3">类的派生类。虽然</font><font FACE="Times New Roman" SIZE="3">CPropertySheet</font><font SIZE="3">不是</font><font FACE="Times New Roman" SIZE="3">CDialog</font><font SIZE="3">类的派生类,但使用</font><font FACE="Times New Roman" SIZE="3">CPropertySheet</font><font SIZE="3">对象的方法与使用</font><font FACE="Times New Roman" SIZE="3">CDialog</font><font SIZE="3">对象是类似的。标签式对话框是一种特殊的对话框,因此,和普通对话框相比,它的设计与实现既有许多相似之处,又有一些不同的特点。</font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY"></font><font SIZE="3">创建一个标签式对话框一般包括以下几个步骤:</p>
    <blockquote>
      <blockquote>
        <p ALIGN="JUSTIFY">分别为各个页创建对话框模板,去掉缺省的</font><font FACE="Times New Roman" SIZE="3">OK</font><font SIZE="3">和</font><font FACE="Times New Roman" SIZE="3">Cancel</font><font SIZE="3">按钮。每页的模板最好具有相同的尺寸,如果尺寸不统一,则框架将根据最大的页来确定标签对话框的大小。在创建模板时,需要在模板属性对话框中指定下列属性:</p>
        <blockquote>
          <blockquote>
            <p ALIGN="JUSTIFY">指定标题</font><font FACE="Times New Roman" SIZE="3">(Caption)</font><font SIZE="3">的内容。标题的内容将显示在该页对应的标签中。</p>
            <p ALIGN="JUSTIFY">选择</font><font FACE="Times New Roman" SIZE="3">TitleBar</font><font SIZE="3">、</font><font FACE="Times New Roman" SIZE="3">Child</font><font SIZE="3">、</font><font FACE="Times New Roman" SIZE="3">ThinBorder</font><font SIZE="3">和</font><font FACE="Times New Roman" SIZE="3">Disable</font><font SIZE="3">属性。</p>
          </blockquote>
        </blockquote>
        <p ALIGN="JUSTIFY">根据各个页的模板,用</font><font FACE="Times New Roman" SIZE="3">ClassWizard</font><font SIZE="3">分别为每个页创建</font><font FACE="Times New Roman" SIZE="3">CPropertyPage</font><font SIZE="3">类的派生类。这一过程与创建普通对话框类的过程类似,不同的是在创建新类对话框中应在</font><font FACE="Times New Roman" SIZE="3">Base class</font><font SIZE="3">一栏中选择</font><font FACE="Times New Roman" SIZE="3">CPropertyPage</font><font SIZE="3">而不是</font><font FACE="Times New Roman" SIZE="3">CDialog</font><font SIZE="3">。</p>
        <p ALIGN="JUSTIFY">用</font><font FACE="Times New Roman" SIZE="3">ClassWizard</font><font SIZE="3">为每页加入与控件对应的成员变量,这个过程与为普通对话框类加入成员变量类似。</p>
        <p ALIGN="JUSTIFY">程序员可直接使用</font><font FACE="Times New Roman" SIZE="3">CPropertySheet</font><font SIZE="3">类,也可以从该类派生一个新类。除非要创建一个非模态对话框,或要在框架对话框中加入控件,否则没有必要派生一个新类。如果直接使用</font><font FACE="Times New Roman" SIZE="3">CPropertySheet</font><font SIZE="3">类,则一个典型的标签式对话框的创建代码如清单</font><font FACE="Times New Roman" SIZE="3">5.12</font><font SIZE="3">所示,该段代码也演示了标签式对话框与外界的数据交换。这些代码通常是放在显示对话框的命令处理函数中。可以看出,对话框框架的创建过程及对话框与外界的数据交换机制与普通对话框是一样的,不同之处是还需将页对象加入到</font><font FACE="Times New Roman" SIZE="3">CPropertySheet</font><font SIZE="3">对象中。如果要创建的是模态对话框,应调用</font><font FACE="Times New Roman" SIZE="3">CPropertySheet::DoModal</font><font SIZE="3">,如果想创建非模态对话框,则应该调用</font><font FACE="Times New Roman" SIZE="3">CPropertySheet::Create</font><font SIZE="3">。</p>
        <p ALIGN="JUSTIFY">若从</font><font FACE="Times New Roman" SIZE="3">CPropertySheet</font><font SIZE="3">类派生了一个新类,则应该将所有的页对象以成员变量的形式嵌入到派生类中,并在派生类的构造函数中调用</font><font FACE="Times New Roman" SIZE="3">CPropertySheet::AddPage</font><font SIZE="3">函数来把各个页添加到对话框中。这样,在创建标签式对话框时就不用做添加页的工作了。</p>
        </font>
      </blockquote>
    </blockquote>
    <p><b><font SIZE="3"> </p>
    <p ALIGN="JUSTIFY">清单</font><font FACE="Times New Roman" SIZE="3">5.12 </font><font SIZE="3">典型的标签式对话框创建代码</font></b><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY">void CMyView::DoModalPropertySheet()</p>
    <p ALIGN="JUSTIFY">{</p>
    <p ALIGN="JUSTIFY">CPropertySheet propsheet;</p>
    <p ALIGN="JUSTIFY">CMyFirstPage pageFirst; // derived from CPropertyPage</p>
    <p ALIGN="JUSTIFY">CMySecondPage pageSecond; // derived from CPropertyPage</p>
    <p ALIGN="JUSTIFY"></font><font SIZE="3"> </font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY">// Move member data from the view (or from the currently</p>
    <p ALIGN="JUSTIFY">// selected object in the view, for example).</p>
    <p ALIGN="JUSTIFY">pageFirst.m_nMember1 = m_nMember1; </p>
    <p ALIGN="JUSTIFY">pageFirst.m_nMember2 = m_nMember2;</p>
    <p ALIGN="JUSTIFY"></font><font SIZE="3"> </font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY">pageSecond.m_strMember3 = m_strMember3;</p>
    <p ALIGN="JUSTIFY">pageSecond.m_strMember4 = m_strMember4;</p>
    <p ALIGN="JUSTIFY"></font><font SIZE="3"> </font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY">propsheet.AddPage(&amp;pageFirst);</p>
    <p ALIGN="JUSTIFY">propsheet.AddPage(&amp;pageSecond);</p>
    <p ALIGN="JUSTIFY"></font><font SIZE="3"> </font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY">if (propsheet.DoModal() == IDOK)</p>
    <p ALIGN="JUSTIFY">{</p>
    <p ALIGN="JUSTIFY">m_nMember1 = pageFirst.m_nMember1;</p>
    <p ALIGN="JUSTIFY">m_nMember2 = pageFirst.m_nMember2;</p>
    <p ALIGN="JUSTIFY">m_strMember3 = pageSecond.m_strMember3;</p>
    <p ALIGN="JUSTIFY">m_strMember4 = pageSecond.m_strMember4; </p>
    <p ALIGN="JUSTIFY"><b>. . . </b></p>
    <p ALIGN="JUSTIFY">}</p>
    <p ALIGN="JUSTIFY">}</p>
    <b><p ALIGN="JUSTIFY"></b></font><font color="#3973DE" FACE="Times New Roman" SIZE="3">.5.2 
    </font><font SIZE="3" color="#3973DE">标签式对话框的运行机制</font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY"></font><font SIZE="3">标签式对话框的初始化包括框架对话框的初始化和页的初始化。页的初始化工作可在</font><font FACE="Times New Roman" SIZE="3">OnInitDialog</font><font SIZE="3">函数中进行,而框架对话框的初始化应该在</font><font FACE="Times New Roman" SIZE="3">OnCreate</font><font SIZE="3">函数中完成。</font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY"></font><font SIZE="3">根据</font><font FACE="Times New Roman" SIZE="3">CPropertySheet::DoModal</font><font SIZE="3">返回的是</font><font FACE="Times New Roman" SIZE="3">IDOK</font><font SIZE="3">还是</font><font FACE="Times New Roman" SIZE="3">IDCANCEL</font><font SIZE="3">,程序可判断出关闭对话框时按的是</font><font FACE="Times New Roman" SIZE="3">OK</font><font SIZE="3">还是</font><font FACE="Times New Roman" SIZE="3">Cancel</font><font SIZE="3">按钮,这与普通对话框是一样的。</font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY"></font><font SIZE="3">如果标签式对话框是模态对话框,在其底部会有三个按钮,依次为</font><font FACE="Times New Roman" SIZE="3">OK</font><font SIZE="3">、</font><font FACE="Times New Roman" SIZE="3">Cancel</font><font SIZE="3">和</font><font FACE="Times New Roman" SIZE="3">Apply</font><font SIZE="3">(应用)按钮,如果对话框是非模态的,则没有这些按钮。</font><font FACE="Times New Roman" SIZE="3">OK</font><font SIZE="3">和</font><font FACE="Times New Roman" SIZE="3">Cancel</font><font SIZE="3">按钮的意义与普通对话框没什么两样,</font><font FACE="Times New Roman" SIZE="3">Apply</font><font SIZE="3">按钮则是标签对话框所特有的。普通的模态对话框只有在用户按下了</font><font FACE="Times New Roman" SIZE="3">OK</font><font SIZE="3">按钮返回后,对话框的设置才能生效,而设计</font><font FACE="Times New Roman" SIZE="3">Apply</font><font SIZE="3">按钮的意图是让用户能在不关闭对话框的情况下使对话框中的设置生效。由此可见,</font><font FACE="Times New Roman" SIZE="3">Apply</font><font SIZE="3">的作用与前面例子中登录数据的“添加”按钮类似,用户不必退出对话框,就可以反复进行设置,这在某些应用场合下是很有用的。</font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY"></font><font SIZE="3">为了对上述三个按钮作出响应,</font><font FACE="Times New Roman" SIZE="3">CPropertyPage</font><font SIZE="3">类提供了</font><font FACE="Times New Roman" SIZE="3">OnOK</font><font SIZE="3">、</font><font FACE="Times New Roman" SIZE="3">OnCancel</font><font SIZE="3">和</font><font FACE="Times New Roman" SIZE="3">OnApply</font><font SIZE="3">函数,用户可覆盖这三个函数以完成所需的工作。需要指出的是这三个函数并不是直接响应按钮的</font><font FACE="Times New Roman" SIZE="3">BN_CLICKED</font><font SIZE="3">消息的,但在按钮按下后它们会被间接调用。这些函数的说明如下:</p>
    <blockquote>
      <blockquote>
        </font><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">virtual void OnOK( );<br>
        </font><font SIZE="3">在按下</font><font FACE="Times New Roman" SIZE="3">OK</font><font SIZE="3">或</font><font FACE="Times New Roman" SIZE="3">Apply</font><font SIZE="3">按钮后,该函数将被调用。缺省的</font><font FACE="Times New Roman" SIZE="3">OnOK</font><font SIZE="3">函数几乎什么也不干,象数据交换和关闭对话框这样的工作是在别的地方完成的,这与普通对话框的</font><font FACE="Times New Roman" SIZE="3">OnOK</font><font SIZE="3">函数是不同的。</p>
        </font><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">virtual void OnCancel( );<br>
        </font><font SIZE="3">在按下</font><font FACE="Times New Roman" SIZE="3">Cancel</font><font SIZE="3">按钮后,该函数将被调用。缺省的</font><font FACE="Times New Roman" SIZE="3">OnCancel</font><font SIZE="3">函数也是几乎什么都不干。</p>
        </font><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">virtual BOOL OnApply( );<br>
        </font><font SIZE="3">在按下</font><font FACE="Times New Roman" SIZE="3">OK</font><font SIZE="3">或</font><font FACE="Times New Roman" SIZE="3">Apply</font><font SIZE="3">按钮后,该函数将被调用。缺省的</font><font FACE="Times New Roman" SIZE="3">OnApply</font><font SIZE="3">会调用</font><font FACE="Times New Roman" SIZE="3">OnOK</font><font SIZE="3">函数。函数的返回值如果是</font><font FACE="Times New Roman" SIZE="3">TRUE</font><font SIZE="3">,则对话框中的设置将生效,否则无效。</font></p>
      </blockquote>
    </blockquote>
    <p><font SIZE="3"> </font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY"></font><font SIZE="3">按理说,</font><font FACE="Times New Roman" SIZE="3">CPropertySheet</font><font SIZE="3">类也应该提供上述函数,特别是</font><font FACE="Times New Roman" SIZE="3">OnApply</font><font SIZE="3">。但奇怪的是,</font><font FACE="Times New Roman" SIZE="3">MFC</font><font SIZE="3">并未考虑</font><font FACE="Times New Roman" SIZE="3">CPropertySheet</font><font SIZE="3">类的按钮响应问题。读者不要指望能通过</font><font FACE="Times New Roman" SIZE="3">ClassWizard</font><font SIZE="3">来自动创建按钮的</font><font FACE="Times New Roman" SIZE="3">BN_CLICKED</font><font SIZE="3">消息处理函数,如果需要用到这类函数,那么只好手工创建了。</font><font FACE="Times New Roman" SIZE="3"></p>
    <p ALIGN="JUSTIFY"></font><font SIZE="3">下列几个</font><font FACE="Times New Roman" SIZE="3">CPropertyPage</font><font SIZE="3">类的成员函数也与标签对话框的运行机制相关。</p>
    <blockquote>
      <blockquote>
        </font><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">void SetModified( BOOL 
        bChanged = TRUE );<br>
        </font><font SIZE="3">该函数用来设置修改标志。若参数</font><font FACE="Times New Roman" SIZE="3">bChanged</font><font SIZE="3">为</font><font FACE="Times New Roman" SIZE="3">TRUE</font><font SIZE="3">,则表明对话框中的设置已改动,否则说明设置未改动。该函数的一个主要用途是允许或禁止</font><font FACE="Times New Roman" SIZE="3">Apply</font><font SIZE="3">按钮。在缺省情况下,</font><font FACE="Times New Roman" SIZE="3">Apply</font><font SIZE="3">按钮是禁止的。只要一调用</font><font FACE="Times New Roman" SIZE="3">SetModified(TRUE)</font><font SIZE="3">,</font><font FACE="Times New Roman" SIZE="3">Apply</font><font SIZE="3">按钮就被允许,而调用</font><font FACE="Times New Roman" SIZE="3">SetModified(FALSE)</font><font SIZE="3">并不一定能使</font><font FACE="Times New Roman" SIZE="3">Apply</font><font SIZE="3">按钮禁止,只有在所有被标为改动过的页都调用了</font><font FACE="Times New Roman" SIZE="3">SetModified(FALSE)</font><font SIZE="3">后,</font><font FACE="Times New Roman" SIZE="3">Apply</font><font SIZE="3">按钮才会被禁止。另外,该函数对</font><font FACE="Times New Roman" SIZE="3">OnApply</font><font SIZE="3">的调用也有影响,当</font><font FACE="Times New Roman" SIZE="3">Apply</font><font SIZE="3">按钮被按下后,只有那些被标为改动过的页的</font><font FACE="Times New Roman" SIZE="3">OnApply</font><font SIZE="3">函数才会被调用。在调用该函数之前,程序需要判断页中的内容是否已被修改,可以通过处理诸如</font><font FACE="Times New Roman" SIZE="3">BN_CLICKED</font><font SIZE="3">、</font><font FACE="Times New Roman" SIZE="3">EN_CHANG</font><font SIZE="3">这样的控件通知消息来感知页的内容的改变。</p>
        </font><font FACE="Times New Roman" SIZE="3"><p ALIGN="JUSTIFY">virtual BOOL OnSetActive( 
        );<br>

⌨️ 快捷键说明

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