📄 08.2.3 向导的创建8.3 本章小结.txt
字号:
图 8 .66为列表框控件添加成员变量
井在 DoDataE xchange函数中添加了下面这条调用 DDX_LBString函数的代码,从而实现列表框控件与成员变量的数据交换:
DDX_LBString(pDX, IDC_L工 ST1, ffi_workAddr);
同样,我们可以在 CProp1类的 OnWizardNext函数中对列表框控件相关联的成员变量进行判断,检查用户是否选择了一个工作地点。如果 workAddr变量为空,那么说明用户没有选择工作地点, OnWizardNext函数就返回一个一 l值,禁止进入下一个属性页。添加的代码为例 8-14代码中加灰显示的部分。
例 8-14
LRESULT CProp1 : : OnW工 zardNext ()
// TODO : Add your specialized code here and/or call the base class
UpdateData() ;
if(m_occupation -1)
MessageBox
别(
return -1;
if (m_workAddr "") MessageBox ( "请选择你的工作地点 !");
return -1 ;
return CPropertyPage : :OnWizardNext() ;
读者可以测试这时的 Prop程序,将发现如果不选择工作地点的话,程序会显示一个对话框,提示用户:"请选择你的工作地点!",并且不会进入下一个属性页面。只有选择了职业和工作地点之后,才能进入下一个属性页面。
2.处理第二个页面第二个属性页面上面是四个复选框,同样,为这个四个控件分别关联一个成员变量。
结果如表8.4所示。
表8.4为第二个属性页上四个重选框控件添加的成员变量
校件 成员变量 变量类型
IDC CHECKI m football BOOL
IDC cf伍CK2 m basketbal1 BOOL
lDC CHECK3 m_volleyball BOOL
IDC CHECK4 m sWlm BOOL
对于复选框控件来说,当选中时,它所关联的成员变量的值应该为 TRUE,否则为
FALSE。 在Prop2类的构造函数 (如例 8-15所示代码)中,可以看到它将新添加的四个成
员变量都初始化为 FALSE。
例8-15
CProp2 : : CProp2() : CPropertyPage(CProp2 ::工00)
{ // {{AFX_ DATA_ INIT{CProp2) ffi_football = FALSE; ffi_basketball = FALSE; ffi_volleyball = FALSE; ffi_swiffi = FALSE; // }}AFX_DATA_ INIT
。
我们希望程序实现:如果用户没有选择任何一个兴趣爱好,就不让程序进入下一个属性页面。因此,同前面的第一个属性页一样,首先为CProp2类添加OnWizardNext虚函数的重写。然后在此函数中,对用户是否做出选择进行判断。实际上,对这四个成员变量,如果有任有一个变量为 TRUE,就可以进入下一个属件页面:否则显示一个对话框,提示用户必须先选择一个兴趣爱好,然后该虚函数返回一1,禁止程序进入下一个属性页。同时,读者需要注意一点,根据前面对第一个属性页面的处理,我们有了这样的经验,就是在对与控件相关联的变量进行判断之前,需要调用UpdateData函数,以实现控件与成员变量的数据交换。因此,具体实现代码如例8-16所示。
1~IJ 8-16
LRESULT CProp2 : :OnWizardNext()
1. // TODO : Add your specialized code here and/or call the base class
2 . UpdateData() ;
3. if ( m_football || m_ basketball || m_volleyball || m_SWim)
4 . return CPropertyPage : : OnWizardNext() ;
5 . else
6. {
7. MessageBox( "请选择你的兴趣爱好!") ;
8 . return -1 ;
9. }
在编写程序时,一定要灵活,不要总是最后才调用阳C fI #J添加
的代码。这里,判断这四个变量任一个为具,比判断它们同时为假要好理解得多。因此,如果满足这个条件,就调用 MFC为我们添加的默认代码(上述第 4行代码),进入下一个属性页。否则,再进行一些提示处理,并且不让程序进入下一个属性页。
Build并运行 Prop程序,打开向导对话框,当进入第二个属性页后,小做出任何选择,直接单击【下一步】按钮,程序立即会弹出一个对话框,提示:"请选择你的兴趣爱好 !"。程序运行界面如图 8.67所示。只要用户选择了一种兴趣爱好,单击【下一步】按钮,就可以进入下一个属性页。
3.处理第三个页面
第三个属性页中摆放的是一个组合框控件,这时,我们要向这个组合框中添加一些薪资选项,以便用户进行选择。组合框控件由一个编辑框和一个列表框组成,其相对应的 MFC类是 CComboBox,该类也有一个成员函数 :AddString,用来向组合框控件的列表框中添加字符串选工页。因此,首先为 CProp3类添加 WM INITDlALOG消息的响应函数,在此函数中对这个属性页对话框进行初始化,即在此函数中调用组合框对象的 AddString函数,向组合框控件的列表框中添加一些薪资选工页,具体代码如例 8-17所示。
19'J 8-17
BOOL CProp3 : :OnlnitDialog()
CPropertyPage : :OnlnitDialog() ;
11 TODO : Add extra initialization here
((CComboBox*)GetDlgltern(工 DC_COMB03) )→AddString("1000元以下 11 ) i
((CComboBox*)GetDlg It ern(IDC_COMB03))->AddString("1000-2000元" ) ;
((CComboBox*)GetDlgltern(IDC一COMB03) ) ->AddString ("2000-3000 7C" ) ;
((CComboBox*)GetDlg工 tern(工 DC_COMB03) )->AddString("3000元以上 11 ) ;
return TRUE ; 11 return TRUE unless you set the focus to a control
11 EXCEPTION : OCX Property Pages should return FALSE
上述例 8-17所示代码中,首先调用 GetDIgItem函数得到指向组合框控件的指针,可是这个函数返回的是 CWnd类型的指针,而我们需要的是 CCo mboBox类型的指针,因此需要进行强制转换。然后,利用这个组合框对象指针,调用 AddString成员函数添加四个薪资选工页。
Build并运行 Prop程序,井打开向导对话框,当进入第三个属性页时,可以看到在组合框的列表框中有了四个薪资远项,如图 8.68所示。
但是,我们发现这四个选项的显示顺序与代码中添加的顺序不一样。这主要是因为组合框默认情况下具有排序的功能,可以打开这个组合框控件的属性对话框,并选择 Styles选项卡,如图 8.69所示。可以看到该组合框控件选中了 " Sort "这个选工页。如果希望组合框的列表框中的字符串按照、代码中添加的顺序显示的话,那么就应该取消这个 "Sort"选工页。本例中取消这个选工页。
图 8.68添加薪资水平选顶之后的效果
读者可以再次运行 Prop程序,井打开向导对话框,运行到第三个属性页的显示,单击组合框右边的下拉箭头,这时会发现下拉列表框中的字符串是按照程序代码中添加的顺序显示的。
另外,我们希望在第三个属性页对话框初始显示时,这个组合框在其编辑框中有一个初始选择的工页,这可以通过组合框的一个成员函数: SetCurSel来完成,该函数的功能是选择组合框的列表框中的一个字符串,并将其显示在该组合框的编辑框中。 SetCurSel函数的声明原型如下所示:
int SetCurSel( int nSelect );
该函数有一个参数: nSe lect,是一个基于 O的索引,指定选择项的索引位置。如果其值为-1,那么将移除该组合框的当前选择,并清空该组合框的编辑框中的内容。因此,在 CProp3类的 OnInitDialog函数(上述例 8-17所示代码)中添加下面这条语句,让组合框初始显示时选中第一个选工页。
.
((CComboBox*)GetDlgItem(IDC_COMBO3))->SetCurSel(O) ;
Build井运行 Prop程序,并打开向导对话框,当进入第三个属性页时,可以看到组合框当前选中的是第一个选项,如图 8 .70所示。既然这个组合框有了默认的选项,那么在程序中就不需要再判断用户是否进行了选择了。
图 8.70向导的第三个属性页
4 .接收用户在向导中所做的选择
下面,我们要实现这样的功能, PrOp程序要将向导中用户的选择输出到视类的窗口中。为了在视类中得到用户在这三个页面中所进行的选择,首先为第三个页面添加一个 CString类型的成员变量 : m_s trS a1町,用来接收用户的选择。然后,程序应该在用户单击向导的【完成】按钮时,将用户所作的薪资水平选择保存到这个变量中,所以应该给 C Prop3类添加一个虚函数 : On WizardFinish,以处理【完成】按钮的单击消息。
为了获取用户选择的薪资选工页,首先需要得到该选项的索引值,这可以利用 CComboB ox类的 Ge tCurS el成员函数来实现,该函数的返回值是一个基于 O的索引,表明组合框的列表框中当前选中项的位置。
获得用户选择的薪资选项索引之后,可以再利用 CComboBox类的另一个成员函数: GetLBText从组合框的列表框中指定位置处得到一个字符串,该函数有两种声明原型,其中一种如下所示 :
void GetLBText( int n工 ndex, CString& rString ) const;
应函数有两个参数,第一个参数指定列表框中将被复制的字符串的索引位置,本例就
可以将它设置为 GetCurSel函数的返回值,即得到当前选中项的字符串。第二个参数就是
指定用来接收复制字符串的缓存。
因此, CProp3类的 OnWizardFinish函数的实现代码如例 8-18所示。
例8-18
BOOL CProp3: : OnWizardFinish ()
// TODO : Add your special工zed code here and/ or call the base class
int index;
index= ((CComboBox* )GetDlgltem(IDC_ COMB03) )->GetCurSel() ;
( (CComboBox*)GetDlgItem (IDC_COMBO3))->GetLBText(index,m_strSalary) ;
return CPropertyPage : :OnWizardFinish() ;
为了接收用户在向导中做出的选择,在视类中需要定义一些变量来保存它们,表 8.5中列出了为视类添加的成员变量,并且,将它们的访问权限都设置为私有的。
表8.5视类添加的成员变量
页面 用户的选择 对应的视类成员变量类型 对应的视类成员变量名称
第一个页面 职业 101 m_iOccupation
第一个页面 工作地点 CString m_strWorkAddr
第二个页面 爱好 BOOL m_bLike[4)
第三个页面 薪资水平 CString m_strSalary
然后,在视类的构造函数中初始化这些添加的变量,代码如例8-19所示。 例8-19
CPropView : : CPropView ( )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -