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

📄 chap5_3.htm

📁 很不错的一本关于VC的书
💻 HTM
📖 第 1 页 / 共 5 页
字号:
    alt="T5_9.tif (186424 bytes)" WIDTH="547" HEIGHT="324"></span></p>    <p ALIGN="center"><span style="font-size: 9pt">图5.9 对话框的数据交换</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt"><font color="#3973DE">5.3.5对话框的运行机制</font></span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">在程序中运行模态对话框有两个步骤:</span></p>    <blockquote>      <p ALIGN="JUSTIFY"><span style="font-size: 9pt">在堆栈上以变量的形式构建一个对话框对象。</span></p>      <p ALIGN="JUSTIFY"><span style="font-size: 9pt">调用CDialog::DoModal ( )。</span></p>    </blockquote>    <p><span style="font-size: 9pt"> </span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">DoModal负责对模态话框的创建和撤销。在创建对话框时,DoModal的任务包括载入对话框模板资源、调用OnInitDialog初始化对话框和将对话框显示在屏幕上。完成对话框的创建后,DoModal启动一个消息循环,以响应用户的输入。由于该消息循环截获了几乎所有的输入消息,使主消息循环收不到对对话框的输入,致使用户只能与模态对话框进行交互,而其它用户界面对象收不到输入信息。</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">若用户在对话框内点击了ID为IDOK的按钮(通常该按钮的标题是“确定”或“OK”),或按了回车键,则CDialog::OnOK将被调用。OnOK首先调用UpdateData(TRUE)将数据从控件传给对话框成员变量,然后调用CDialog::EndDialog关闭对话框。关闭对话框后,DoModal会返回值IDOK。</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">若用户点击了ID为IDCANCEL的按钮(通常其标题为“取消”或“Cancel”),或按了ESC键,则会导致CDialog::OnCancel的调用。该函数只调用CDialog::EndDialog关闭对话框。关闭对话框后,DoModal会返回值IDCANCEL。</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">程序根据DoModal的返回值是IDOK还是IDCANCEL就可以判断出用户是确定还是取消了对对话框的操作。</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">在弄清了对话框的运行机制后,下面让我们来就可以实现Register程序登录数据的功能。</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">首先,将Register工程的工作区切换至资源视图。打开IDR_MAINFRAME菜单资源,在Edit菜单的底端加入一个名为“登录数据”的新菜单项,并令其ID为ID_EDIT_REGISTER(最好在该项之前加一条分隔线,以便和前面的菜单项分开)。注意不要忘了把菜单资源的语种设置成中文,否则菜单中将显示不出中文来。设置的方法是先在工作区资源视图中选择IDR_MAINFRAME菜单资源,然后按Alt+Enter键,并在弹出的属性对话框中的Language栏中选择Chinese(P.R.C.)。</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">接着,用ClassWizard为该菜单命令创建命令处理函数CRegisterView::OnEditRegister。注意,OnEditRegister是类CRegisterView的成员函数,这是因为CRegisterView要负责打开和关闭登录数据对话框,并将从对话框中输入的数据在视图中输出。</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">然后,请读者在RegisterView.cpp文件的开头加入下面一行</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">#include &quot;RegisterDialog.h&quot;</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">最后,按清单5.4修改程序。</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt"> </span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">清单5.4 OnEditRegister函数</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">void CRegisterView::OnEditRegister() </span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">{</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">// TODO: Add your command handler code     here</span></p>    <p><span style="font-size: 9pt"> </span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">CRegisterDialog dlg;</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt"> </span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">if(dlg.DoModal()==IDOK)</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">{</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">CString str;</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">//获取编辑正文</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">GetWindowText(str);</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">str+=&quot;\r\n&quot;;</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt"> </span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">str+=&quot;姓名:&quot;;</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">str+=dlg.m_strName;</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">str+=&quot;\r\n&quot;;</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt"> </span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">str+=&quot;性别:&quot;;</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">str+=dlg.m_nSex?&quot;女&quot;:&quot;男&quot;;</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">str+=&quot;\r\n&quot;;</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt"> </span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">str+=&quot;年龄:&quot;;</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">CString str1;</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">//将数据格式输出到字符串对象中</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">str1.Format(&quot;%d&quot;,dlg.m_nAge);</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">str+=str1;</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">str+=&quot;\r\n&quot;;</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt"> </span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">str+=&quot;婚否:&quot;;</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">str+=dlg.m_bMarried?&quot;已婚&quot;:&quot;未婚&quot;;</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">str+=&quot;\r\n&quot;;</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt"> </span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">str+=&quot;就业状况:&quot;;</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">str+=dlg.m_nWork?&quot;下岗&quot;:&quot;在职&quot;;</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">str+=&quot;\r\n&quot;;</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt"> </span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">str+=&quot;工作单位:&quot;;</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">str+=dlg.m_strUnit;</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">str+=&quot;\r\n&quot;;</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt"> </span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">str+=&quot;单位性质:&quot;;</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">str+=dlg.m_strKind;</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">str+=&quot;\r\n&quot;;</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt"> </span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">str+=&quot;工资收入:&quot;;</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">str+=dlg.m_strIncome;</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">str+=&quot;\r\n&quot;;</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">SetWindowText(str);</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">在OnEditRegister函数中,首先构建了一个CRegisterDialog对象,然后调用CDialog::DoModal来实现模态对话框。如果DoModal返回IDOK,则说明用户确认了登录数据的操作,程序需要将录入的数据在编辑视图中输出。程序用一个CString对象来作为编辑正文的缓冲区,CString是一个功能强大的字符串类,它的最大特点在于可以存储动态改变大小的字符串,这样,用户不必担心字符串的长度超过缓冲区的大小,     使用十分方便。</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">在输出数据时,程序首先调用CWnd::GetWindowText获得编辑正文,这是一个多行的编辑正文。CWnd::GetWindowText用来获取窗口的标题,若该窗口是一个控件,则获取的是控件内的正文。CRegisterView是CEditView的继承类,而CEditView实际上包含了一个编辑控件,因此在CRegisterView中调用GetWindowText获得的是编辑正文。</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">然后,程序在该编辑正文的末尾加入新的数据。在程序中大量使用了CString类的重载操作符“+=”,该操作符的功能是将操作符右侧字符串添加到操作符左侧的字符串的末尾。注意在多行编辑控件中每行末尾都有一对回车和换行符。在程序中还调用了CString::Format来将数据格式化输出到字符串中,Format的功能与sprintf类似。最后,调用CWnd::SetWindowText来更新编辑视图中的正文。</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">编译并运行Register,打开登录数据对话框,输入一些数据试试。现在,Register已经是一个简易的数据库应用程序了,它可以将与就业情况有关的数据输出到一个编辑视图中。用户可以编辑视图中的正文,并将结果保存在文本文件中。</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt"><font color="#3973DE">5.3.6处理控件通知消息</font></span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">虽然Register已经可以登录数据了,但读者会很快会发现该程序还有一些不完善的地方:</span></p>    <blockquote>      <p ALIGN="JUSTIFY"><span style="font-size: 9pt">登录完一个人的数据后,对话框就关闭了,若用户有很多人的数据要输入,则必须频繁地打开对话框,很不方便。在登录数据时,应该使对话框一直处于打开状态。</span></p>      <p ALIGN="JUSTIFY"><span style="font-size: 9pt">登录数据对话框分个人情况和单位情况两组,若被调查人是下岗职工,则不必输入单位情况。程序应该能够对用户的输入及时地作出反应,即当用户选择了“下岗”单选按钮时,应使单位情况组中的控件禁止。一个禁止的控件呈灰色示,并且不能接收用户的输入。</span></p>    </blockquote>    <p><span style="font-size: 9pt"> </span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">要解决上述问题,就必须对控件通知消息进行处理。当控件的状态因为输入等原因而发生变化时,控件会向其父窗口发出控件通知消息。例如,如果用户在登录数据对话框中的某一按钮(包括普通按钮、检查框和单选按钮)上单击鼠标,则该按钮会向对话框发送BN_CLICKED消息。对话框根据按钮的ID激活相应的BN_CLICKED消息处理函数,以对单击按钮这一事件作出反应。通过对按钮的BN_CLICKED消息的处理,我们可以使登录数据对话框的功能达到上述要求。</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">首先,让我们来解决第一个问题。我们的设想是修改原来的“确定(Y)”按钮,使得当用户点击该按钮后,将数据输出到视图中,并且对话框不关闭,以便用户输入下一个数据。请读者按下面几步进行修改。</span></p>    <blockquote>      <p ALIGN="JUSTIFY"><span style="font-size: 9pt">修改登录数据对话框的“确定(Y)”按钮,使该按钮的标题变为“添加(&amp;A)”,ID变为IDC_ADD。这样,当用户点击该按钮后,对话框会收到BN_CLICKED消息。由于这个BN_CLICKED消息对应的按钮ID不是IDOK,不会触发OnOK消息处理函数,因此不会关闭对话框。</span></p>      <p ALIGN="JUSTIFY"><span style="font-size: 9pt">为按钮IDC_ADD的BN_CLICKED消息创建消息处理函数。创建的方法是进入ClassWizard后,选Message       Maps页并在Class name栏中选择CRegisterDialog,然后在Object IDs栏中选择IDC_ADD,在Messages栏中双击BN_CLICKED。在确认使用缺省的消息处理函数名OnAdd后,按回车键退出ClassWizard。</span></p>      <p ALIGN="JUSTIFY"><span style="font-size: 9pt">OnAdd要向编辑视图输出正文,就必须获得一个指向CRegisterView对象的指针以访问该对象。为此,请在CRegisterDialog类的说明中加入下面一行<br>      Cwnd* m_pParent;<br>      注意不要加在AFX注释对中。</span></p>      <p ALIGN="JUSTIFY"><span style="font-size: 9pt">为实现IDC_ADD按钮的功能,请按清单5.5和清单5.6修改程序。主要的改动是把原来由CRegiserView::OnEditRegister完成的在视图中输出数据的任务交给CRegisterDialog::OnAdd来完成。</span></p>    </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">清单5.5 CRegisterView::OnEditRegister函数</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">void CRegisterView::OnEditRegister() </span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">{</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">// TODO: Add your command handler code     here</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt"> </span></p>    <p><span style="font-size: 9pt"> </span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">CRegisterDialog dlg(this);</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">dlg.DoModal();</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"> </span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">清单5.6 CRegisterDialog类的部分源代码</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">CRegisterDialog::CRegisterDialog(CWnd*     pParent /*=NULL*/)</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">: CDialog(CRegisterDialog::IDD, pParent)</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">{</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">//{{AFX_DATA_INIT(CRegisterDialog)</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">. . . . . .</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">//}}AFX_DATA_INIT</span></p>    <p><span style="font-size: 9pt"> </span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">m_pParent=pParent;</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">void CRegisterDialog::OnAdd() </span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">{</span></p>    <p ALIGN="JUSTIFY"><span style="font-size: 9pt">// TODO: Add your control notification 

⌨️ 快捷键说明

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