友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
富士康小说网 返回本书目录 加入书签 我的书架 我的书签 TXT全本下载 『收藏到我的浏览器』

C语言实例教程(PDF格式)-第29部分

快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!



序)中添加类型为CBitmapButton的新的成员变量m_bnClickhere。  



5。 在OnInitDialog成员函数中的return语句前添加下面的代码:  



m_bnClickhere。AutoLoad(IDC_CLICKHERE; this);  



CRect rect1;rect2;  



CButton *pClickhere=(CButton*)GetDlgItem(IDC_CLICKHERE);  



GetClientRect(&rect1);  



pClickhere…》GetWindowRect(&rect2);  



ScreenToClient(&rect2);  



pClickhere…》MoveWindow(rect2。left;(rect1。Height()…rect2。Height())/2;  



rect2。Width();rect2。Height());  



其中第一个参数IDC_CLICKHERE是位图按钮的资源ID,第二个参数为 

指向该位图按钮的父窗口的CWnd对象的指针,这里即类 

CBitmapButtonDlg的this指针。类CBitmapButton的成员函数 

AutoLoad完成以下几步工作:  



(1) 将按钮与CBitmapButton对象相关联;  


…………………………………………………………Page 327……………………………………………………………

(2)    自动加载按钮所使用的位图,条件是这些位图资源满足步骤2中 

的命名约定;  



(3) 自动改变控件的大小以适合所加载的位图资源。  



接下来的几行代码将位图按钮在对话框中进行垂直居中。首先类CWnd 

的成员函数GetClientRect返回了对话框的客户区矩形,接着,类 

CWnd的成员函数GetWindowRect返回了控件IDC_CLICKHERE的窗口矩 

形,然后使用类CWnd的成员函数ScreenToClient将rect2由屏幕坐标 

转换为对话框的客户坐标,这是因为类CWnd的成员函数MoveWindow在 

移动子窗口时将使用父窗口的客户区坐标,而不是使用屏幕坐标。  



6。  按图6。26添加下面的下压按钮IDC_DISABLE,将其标题设置为 “禁 

止使用 (&X)”。  



                                            



                   图6。 26 位图按钮示例程序对话框的设计  



7。  将所有下压按钮的Tab  stop属性 (位于General选项卡中)设置为 

真。并按图6。26调整各控件的大小位置。其中按钮CLICKHERE的大小 

的无关紧要的,我们只需要保证对话框左边是否有足够的空间来显示 

按钮所使用的位图即可。  



8。 为按钮IDC_DISABLE的BN_CLICKED命令编写下面的命令处理函数:  



void CBitmapButtonDlg::OnDisable()   



{  



CButton *pClickhere=(CButton*)GetDlgItem(IDC_CLICKHERE);  



static int bIsEnabled=pClickhere…》IsWindowEnabled();  



if (bIsEnabled)  



{  



pClickhere…》EnableWindow(FALSE);  



SetDlgItemText(IDC_DISABLE;〃允许使用 (&E)〃);  



}  


…………………………………………………………Page 328……………………………………………………………

else  



{  



pClickhere…》EnableWindow(TRUE);  



SetDlgItemText(IDC_DISABLE;〃禁止使用 (&X)〃);  



}  



bIsEnabled=!bIsEnabled;  



}  



上面的代码实现两个功能,即当位图按钮的状态为允许时,单击按钮 

IDC_DISABLE将其状态设置为不允许;在相反的状态下,单击按钮 

IDC_DISABLE将其状态设置为允许。由于实现该过程的代码比较简 

单,因此我们在这里不作详细的讲述。  



编译并运行上面的示例程序,其结果如图6。27所示。  



反复单击位图按钮和禁止使用按钮,以观察位图按钮在不同状态下的 

外观的改变。还可以使用TAB键改变按钮的输入焦点,以观察位图按 

钮获得输入焦点和失去输入焦点时的不同外观。  



                                            



                        图6。 27 位图按钮示例程序  



6。3。3 组框  



组框也是一种按钮控件。它常常用来在视觉上将控件 (典型情况下是 

一系列的单选钮和复选框)进行分组,从而使对话框中的各个控件看 

起来比较有条理。  



                                            



                      图6。 28 组框 (Group box)控件  



相对于其它控件来说,组框的使用非常之简单。这里我们需要强调的 


…………………………………………………………Page 329……………………………………………………………

是,组框仅仅是在视觉上将控件进行分组,事实上控件在编程上的分 

组依赖于其Group属性的设置。  



组框也可以发送BN_CLICKED和BN_DOUBLECLICKED命令消息。但是在般 

情况下我们都不对这些命令作响应。此外,组框也可以设置Icon或 

Bitmap属性 (注意它们之间的互斥的),即我们可以使用图标或位图来 

代替默认情况下的文本。但是在绝大多数情况下,我们仅使用纯文本 

来作为组框的标题。  



与前面讲述的下压按钮类似,我们同样可以使用SetDlgItemText成员 

函数来设置组框控件的标题文本。此外,我们还可以使用GetDlgItem 

来获得与组框控件相关联的CWnd对象的指针,然后通过该指针调用成 

员函数SetWindowText来实现同样的功能。由于在程序中常常不需要 

频繁的操纵组框控件,因此大多数情况下我们不需要为组框控件进行 

成员变量的映射,但这种方法是完全可以的。  



对于如何将控件进行分组的方法在讲述单选钮和复选框时再作介绍。  



6。3。4 单选钮  



                               



                 图6。 29 单选钮示例程序  



单选钮用来表示一系列的互斥选项,这些互斥选项常常被分成若干个 

组。下面的示例程序说明了单选钮的使用。  



1。        创建新的基于对话框的MFC应用程序,将工程名设置为 

RadioButton。  



2。  按图6。29绘制应用程序的主对话框。其中在Control工具箱中单选 

钮对应的图标是     ,组框控件对应的图标是        。  



3。  单击Layout菜单下的Tab Order命令,按图6。30的顺序单击各控件 

以设置控件的TAB键顺序 (Tab Order)。  



4。  确信所有控件的Group属性都被设置为假。分别单击组框 “性别” 

和组框 “年龄”,将其Group属性设置为真。  


…………………………………………………………Page 330……………………………………………………………

                                



                图6。 30 设置控件的Tab Order  



以Tab  Order为序,从Group属性为真的控件开始 (包括该控件),到下 

一个Group属性的真的控件结束 (不包括该控件),所有的这些控件将 

组成一个组。对于单选钮,同一组内同时只能有(也应该有)一个处于 

被选中的状态。当其中一个控件被置于选中状态时,同组的其它单选 

钮应该清除其选中状态。对于由资源编辑器生成的单选钮控件,在默 

认情况由Windows 自动处理同组控件之间的互斥关系。  



下面我们简述一下特定于单选钮的一些属性及其含义,这些属性被列 

于Styles选项卡内:  



         Auto:  在具有Auto属性的情况下,当用户单击了同 

                一组的某个单选钮时,其余单选钮的选中属 

                性被自动清除。当在一组单选钮中使用 

                Dialog  Data  Exchange时,该属性必须被设 

                置为True。类型:布尔值 默认值:真  



         Left   将单选钮的标题文本显示于圆形标记的左 

         text:  边。类型:布尔值 默认值:假  



         Push 使一个复选框、三态复选框或单选项具有类 

         like:  似于下压按钮的外观和行为。该按钮在选中 

                时显示为凸起,在不被选中时显示为凹下(参 

                见图。类型:布尔值 默认值:假  



         Notify:  决定在默认情况下当单选钮被单击或双击时 

                向父窗口发送通知消息。类型:布尔值  默认 

                值:真  



                                



              图6。 31 具有Pusk…like样式的单选钮  


…………………………………………………………Page 331……………………………………………………………

5。   将性别框内的两个控件的ID按从上到下的顺序设置为IDC_SEX1和 

IDC_SEX2;将年龄框内的两个控件的ID按从上到下的顺序设置为 

IDC_AGE1、IDC_AGE2、IDC_AGE3、IDC_AGE4和IDC_AGE5。  



在程序运行时可以调用CButton的成员函数SetCheck设置单选钮的选 

中状态。该成员函数带有一个类型为整型的参数,该参数为0表示清 

除选中按钮的选中状态,参数为1表示设置选中按钮的选中状态。  



  l 注意:  



  l 如果我们在程序中调用SetCheck设置同一组中某一单选钮的为选 

   中状态,并不意味着同时清除同一组中其它单选钮的选中状态。 

   以前面创建的工程来举例,请看下面的两行代码 :  



  l ((CButton*)GetDlgItem(IDC_AGE1))…》SetCheck(1);  



  l ((CButton*)GetDlgItem(IDC_AGE5))…》SetCheck(1);  



      上面的代码将导致年龄组中的第一个按钮和第五个按钮在对 

      话框第一次显示时同时处于选中状态。这是应该避免的。因 

      此,如果我们通过代码改变了单选钮的选中状态,一定要记 

      得同时清除同组的其它单选钮的选中状态。  



对于单个的单选钮,我们可以调用类CButton的成员函数GetCheck, 

该函数的返回值为0、1或2,分别代表按钮处理未选中状态、选中状 

态或中间状态 (对三态复选框而言)。但是,对于对话框中的单选锯而 

言,我们更感兴趣于同一组单选钮中哪一个被选中,因此,调用类 

CWnd的成员函数GetCheckedRadioButton要更为方便。该成员函数原 

型如下:  



int GetCheckedRadioButton( int nIDFirstButton; int nIDLastButton );  



第一个参数nIDFirstButton是同一组中的第一个单选钮控件的ID, 

nIDLastButton是同一组中最后一个单选钮控件的ID。成员函数 

GetCheckedRadioButton返回指定组中第一个所选中的单选钮 (在正常 

情况下仅应当有一个单钮被选中)的ID,如果没有按钮被选中,则返 

回0。  



这里需要注意的是,成员函数GetCheckedRadioButton被没有要求两 

个参数nIDFirstButton和nIDLastButton所指定的控件一定位于同一 

组中。  


…………………………………………………………Page 332……………………………………………………………

  l 注意:  



  l 若干个单选钮是否属于同一组是以其Tab顺序来排定的,而 

    GetCheckedRadioButton函数是以ID顺序来检查按钮的选定状态 

    的。因此,如果传递给函数GetCheckedRadioButton的第一个参数 

    的值大于第二个参数的值时,其返回值总是为0,而事实上,由这 

    两个参数指定的单选钮的TAB顺序可能恰恰相反。因此,一般情况 

    下我们应该尽量保证同一组单选钮的资源ID是连续递增的。通常 

    这些资源ID是在头文件Resource。h中定义的。如果你同一组的单 

    选钮不是一次创建的,那么它们的资源ID可能不是连续递增的, 

    甚至可能是相反的。这时我们可以手动的修改资源头文件中的宏 

    定义,以保证如GetCheckedRadioButton之类的成员函数得到正确 

    的结果。  



        同时,这也说明一点,即使用GetCheck一个一个控件的检查 

        各单选钮的选中状态要安全得多。  



下面我们来完成应用程序RadioButton 。  



首先,使用ClassWizard重载类CDialog的OnOK成员函数,方法是重载 

ID为IDOK的按钮的BN_CLICKED命令处理函数。由ClassWizard生成的 

默认重载形式如下:  



void CRadioBoxDlg::OnOK()   



{  



// TODO: 在此添加附加的验证  



CDialog::OnOK();  



}  



这里特定的代码来替代前面的// TODO注释后得到如下的程序代码:  



void CRadioBoxDlg::OnOK()   



{  



// 暂时隐藏主对话框  



ShowWindow(SW_HIDE);  



UINT nSex=GetCheckedRadioButton(IDC_SEX1;IDC_SEX2); // 获得性别选择  



UINT nAge=GetCheckedRadioButton(IDC_AGE1;IDC_AGE5); // 获得年龄选择  


…………………………………………………………Page 333……………………………………………………………

CString msg=〃性别: 〃; // 保存输出消息字符串  



// 根据用户的选择生成消息串  



// 添加性别信息  



switch (nSex)  



{  



case IDC_SEX1:  



msg+=〃男n〃;  



break;  



case IDC_SEX2:  



msg+=〃女n〃;  



break;  



default:  



break;  



}  



// 添加年龄信息  



msg+=〃年龄: 〃;  



switch (nAge)  



{  



case IDC_AGE1:  



msg+=〃18 岁以下〃;  



break;  



case IDC_AGE2:  



msg+=〃18 25 岁〃;  



break;  



case IDC_AGE3:  



msg+=〃25 35 岁〃;  


…………………………………………………………Page 334……………………………………………………………

break;  



case IDC_AGE4:  



msg+=〃35 45 岁〃;  



break;  



case IDC_AGE5:  



msg+=〃45 岁以上〃;  



break;  



default:  



break;  



}  



msg+=〃nn 以上数据是否正确?〃;  



// 显示输入消息框询问用户所输入的信息是否正确  



if(MessageBox(msg;NULL;MB_YESNO|MB_ICONQUESTION)==IDNO)  



{  



// 当用户回答 “否”时重新显示对话框以供便用户可以更改所作的选择  



ShowWindow(SW_SHOW);  



return;  



}  



// 否则退出应用程序  



CDialog::OnOK();  



}  



以上应用程序的运行结果如图6。32所示:  



按如图6。32所示进行选择,单击确定弹出如图6。33所示的对话框。  



下一节中我们将讲述复选框的使用。  


…………………………………………………………Page 335……………………………………………………………

                                



               图6。 32 单选钮示例程序的运行结果  



                               



              图6。 33 单击 “确定”之后的确认消息框  



6。3。5 复选框  



复选框与单选钮很相象,不同之处在于在同一组控件中,通常使用复 

选框来代表多重选择,即选项不是互斥的。从外观上来说,复选框所 

使用的选中标记是一个方框和方框里面的小叉,而不是单选钮所使用 

的小圆圈和里面的小点。  



对于编程者来说,复选框和单选钮非常相似。我们通过SetCheck成员 

函数来设置某一复选框的选中状态,通过GetCheck成员函数来获取某 

一复选框的选中状态。一般来说,对于复选框,由于其选项不是互斥 

的,我们一般不通过GetCheckedRadioButton之类的函数来获得处于 

选中状态的按钮。  



以下特定于复选框的样式可以Properties对话框的Styles属性页中进 

行设置:  



         Auto:  对于Auto属性为真的复选框,在单击时将 自动 

               在 “选中”和 “不选中”之间进行切换。如果 

               在一组复选框中使用了Dialog              Data  

               Exchange,则必须将该属性设置为真。类型: 

               布尔值 默认值:真  



         Tri 创建三态复选框。除了处于 “选中”和 “不选 

                

         state: 中”状态外,三态复选框还可以处于变灰状 

               态。通常,态复选框的变灰状态表示其选中状 

               态不确定。在很多软件的安装程序中,变灰往 

               往表示仅选中该组件中的一部分。  


…………………………………………………………Page 336……………………………………………………………

                                             



                    图6。 34 工程CheckBox的主对话框的设计  



下面的应用程序举例说明了复选框的使用。  



1。       使用默认选项创建一个基于对话框的MFC工程,设置工程名为 

CheckBox。  



2。   按图6。34绘制对话框中的各个复选框 (在Control工具箱中复选框 

所对应的图标为            ),并按表6。24设置各复选框的样式和属性。  



                  表6。 24 工程CheckBox中各控件的属性设置  



            控件     ID         标题文本          其它  



            复选     IDC_PLACE1  在家里 (&H)     Auto属性和Tri

            框                               state属性均为真  

                   IDC_PLACE2  在公司办公室 

                              (&O)  



                   IDC_PLACE3  在学校公共机房 

                              (&S)  



                   IDC_OFTEN   经常           Auto属性为假, 

                                            Tri…state属性为 

                   IDC_SELDOM  偶尔           真  



                   IDC_NEVER   从不  



            组框     IDC_STATIC  使用计算机的场 

                                              

                              所  



3。   使用下面的代码替换类CCheckBoxDlg的成员函数OnInitDialog中 

的// TODO注释:  



((CButton*)GetDlgItem(IDC_OFTEN))…》SetCheck(1);  



((CButton*)GetDlgItem(IDC_SELDOM))…》SetCheck(2);  



((CButton*)GetDlgItem(IDC_NEVER))…》SetCheck(0);  



由于三个复选框IDC_OFTEN、IDC_SELDOM、IDC_NEVER的Auto属性值为 


…………………………………………………………Page 337……………………………………………………………

假,因此当用户单击这三个复选框时其状态不会发生改变。它们在本 

示例程序中起了图例的作用。  



4。   在类CCheckBoxDlg中重载类CDialog的成员函数OnOK如下 (关于对 

命令处理成员函数OnOK的重载我们已经在前一小节中作了讲述):  



void CCheckBoxDlg::OnOK()   



{  



// 定义和初始化所用的变量  



CString strMsg; // 消息字符串  



strMsgA'3'; // 分别对应于三种不同时间频度的消息字符串  



int iCount'3'; // 对应于每种时间频度的情况计数  



// 初始化各变量  



iCount'0'=iCount'1'=iCount'2'=0;  



strMsgA'0'=〃从不在〃;  



strMsgA'1'=〃经常在〃;  



strMsgA'2'=〃偶尔在〃;  



int i; // 用着循环变量或中间变量  



// 检查各复选框的选中状态,并根据用户的选择生成对应于三种不同时间  



// 频度的消息字符串  



// 检查复选框 IDC_PLACE1  



i=( (CButton*)GetDlgItem(IDC_PLACE1) )…》GetCheck();  



if ( (iCount'i'++)==0 )  



strMsgA'i'+=〃家里〃;  



else  



strMsgA'i'+=〃、家里〃;  



// 检查复选框 IDC_PLACE2  



i=( (CButton*)GetDlgItem(IDC_PLACE2) )…》GetCheck();  



if ( (iCount'i'++)==0 )  


…………………………………………………………Page 338………………
返回目录 上一页 下一页 回到顶部 9 9
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!