Microsoft Word - 实验3.doc

Similar documents
INTRODUCTION TO COM.DOC

概述

VC访问VB的ActiveX.dll.doc

Microsoft Word - 第3章.doc

无类继承.key

PowerPoint 演示文稿

FY.DOC

Microsoft Word - ch04三校.doc

ebook50-11

C 1

Microsoft PowerPoint - string_kruse [兼容模式]

chap07.key

新・明解C言語入門編『索引』

untitled

<C8EBC3C5C6AAA3A8B5DA31D5C2A3A92E696E6464>

CC213

概述

1 Framework.NET Framework Microsoft Windows.NET Framework.NET Framework NOTE.NET NET Framework.NET Framework 2.0 ( 3 ).NET Framework 2.0.NET F

新版 明解C++入門編

BOOL EnumWindows(WNDENUMPROC lparam); lpenumfunc, LPARAM (Native Interface) PowerBuilder PowerBuilder PBNI 2

一 登录 crm Mobile 系统 : 输入 ShijiCare 用户名和密码, 登录系统, 如图所示 : 第 2 页共 32 页

Microsoft Word - 01.DOC

OOP with Java 通知 Project 4: 4 月 19 日晚 9 点

Microsoft Word - CX1000-HMI_程序开发_PLC通讯

C/C++语言 - C/C++数据

帝国CMS下在PHP文件中调用数据库类执行SQL语句实例

untitled

Microsoft PowerPoint - 8. 运算符重载 Operator Overloading.pptx

1 1 大概思路 创建 WebAPI 创建 CrossMainController 并编写 Nuget 安装 microsoft.aspnet.webapi.cors 跨域设置路由 编写 Jquery EasyUI 界面 运行效果 2 创建 WebAPI 创建 WebAPI, 新建 -> 项目 ->

Microsoft PowerPoint - 4. 数组和字符串Arrays and Strings.ppt [兼容模式]

C/C++ 语言 - 循环

OOP with Java 通知 Project 3: 3 月 29 日晚 9 点 4 月 1 日上课

手册 doc

int *p int a 0x00C7 0x00C7 0x00C int I[2], *pi = &I[0]; pi++; char C[2], *pc = &C[0]; pc++; float F[2], *pf = &F[0]; pf++;

Fun Time (1) What happens in memory? 1 i n t i ; 2 s h o r t j ; 3 double k ; 4 char c = a ; 5 i = 3; j = 2; 6 k = i j ; H.-T. Lin (NTU CSIE) Referenc

C++ 程序设计 实验 2 - 参考答案 MASTER 2017 年 5 月 21 日 1

Microsoft Word - CIN-DLL.doc

提问袁小兵:

SDK 概要 使用 Maven 的用户可以从 Maven 库中搜索 "odps-sdk" 获取不同版本的 Java SDK: 包名 odps-sdk-core odps-sdk-commons odps-sdk-udf odps-sdk-mapred odps-sdk-graph 描述 ODPS 基

1 Project New Project 1 2 Windows 1 3 N C test Windows uv2 KEIL uvision2 1 2 New Project Ateml AT89C AT89C51 3 KEIL Demo C C File

res/layout 目录下的 main.xml 源码 : <?xml version="1.0" encoding="utf 8"?> <TabHost android:layout_height="fill_parent" xml

Java

untitled

《C语言程序设计》教材习题参考答案

Generated by Unregistered Batch DOC TO PDF Converter , please register! 浙江大学 C 程序设计及实验 试题卷 学年春季学期考试时间 : 2003 年 6 月 20 日上午 8:3

Microsoft Word - 把时间当作朋友(2011第3版)3.0.b.07.doc

Microsoft Word - 实验3.doc

文档 3

// HDevelopTemplateWPF projects located under %HALCONEXAMPLES%\c# using System; using HalconDotNet; public partial class HDevelopExport public HTuple

EJB-Programming-4-cn.doc

《C语言程序设计》第2版教材习题参考答案

<4D F736F F F696E74202D20332D322E432B2BC3E6CFF2B6D4CFF3B3CCD0F2C9E8BCC6A1AAD6D8D4D8A1A2BCCCB3D0A1A2B6E0CCACBACDBEDBBACF2E707074>

任務二 : 產生 20 個有炸彈的磚塊, 放在隨機的位置編輯 Block 類別的程式碼 import greenfoot.; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo) Write a description of class

计算机网络实验说明

ebook14-4

Guava学习之Resources

F515_CS_Book.book

c_cpp

OOP with Java 通知 Project 2 提交时间 : 3 月 14 日晚 9 点 另一名助教 : 王桢 学习使用文本编辑器 学习使用 cmd: Power shell 阅读参考资料

C

Microsoft Word - PHP7Ch01.docx

软件工程文档编制

《大话设计模式》第一章

06 01 action JavaScript action jquery jquery AJAX CSS jquery CSS jquery HTML CSS jquery.css() getter setter.css('backgroundcolor') jquery CSS b

C++ 程式設計

epub 94-3

6-1 Table Column Data Type Row Record 1. DBMS 2. DBMS MySQL Microsoft Access SQL Server Oracle 3. ODBC SQL 1. Structured Query Language 2. IBM

User’s Manual

Microsoft Word - CPE考生使用手冊 docx

第3章.doc

OOP with Java 通知 Project 4: 5 月 2 日晚 9 点

,, 1 ( ) 1 / CurrentSeries Int ConnectionString CString Style3D BOOL IsContinue Graph BOOL LegendType Int SeriesName CString SeriesColor OL E

C/C++语言 - 分支结构

2 WF 1 T I P WF WF WF WF WF WF WF WF 2.1 WF WF WF WF WF WF

全国计算机技术与软件专业技术资格(水平)考试

ebook39-5

epub83-1

( CIP) /. :, ( ) ISBN TP CIP ( 2005) : : : : * : : 174 ( A ) : : ( 023) : ( 023)

建模与图形思考

ebook39-6

Strings

untitled


Transcription:

实验 3 常用控件 控件是在系统内部定义的能够完成特定功能的程序单元 在应用程序中使用控件不仅简化了编程, 还能完成常用的各种功能 在所有的控件中, 根据它的使用以及 Visual C++ 6.0 对其支持情况 ( 包括 Visual C++ 6.0 对其更新和扩展 ), 可以把控件分为基本控件 公共控件和 ActiveX 控件 控件的创建方式有两种 一种是在对话框模板中指定控件 ( 既可使用对话框编辑器进行创建, 也可自行定义 ), 这样, 当应用程序启动该对话框时,Windows 系统就会为对话框创建控件 ; 当对话框清除时, 控件也随之清除 另一种方式是将控件看作子窗口, 通过调用 CWnd::Create 函数来创建控件 在本实验 ( 实训 ) 中, 将用对话框模板来设计几个比较有趣的实例 :Ex_Font 能枚举系统中的字体并能显示其样式 ;Ex_Hatch 用来例显控件中图案和颜色绘制的能力 ; Ex_Person 能简单管理学生的个人信息 实验目的 熟悉对话框应用程序的创建 熟悉对话框资源的添加和设计 掌握控件消息和对话框消息的映射 学会在控件上绘制图案 学会在同一个消息函数处理不同控件的消息 熟悉常见问题的处理方法和技巧 实验内容 简单计算器 控件图案绘制 管理学生的个人信息 实验准备和说明 具备知识 : 常用控件 构思并准备上机所需要的程序 Ex_Cal Ex_Hatch 和 Ex_Person 创建本实验 ( 实训 ) 的工作文件夹 D:\Visual C++ 程序 \LiMing\3 3.1 简单计算器 一个简单的计算器常常包含加 减 乘和除四则运算, 由于乘除的运算等级要高于加减, 因此显示结果时需要对输入的表达式按进行运算等级解析 当然, 表达式的输入是通过数字和符号按钮进行的, 如图 3.1(a) 所示, 单击 = 按钮, 结果如图 3.1(b) 所示

54 Visual C++ 实训 ( 第 3 版 ) 本实验 ( 实训 ) 创建的项目为 Ex_Cal, 具体过程如下 : 设计计算器对话框 映射并控制输入 解析并输出结果 (a) (b) 图 3.1 项目 Ex_Cal 运行结果 3.1.1 设计计算器对话框具体步骤如下 : (1) 启动 Visual C++ 6.0, 选择 文件 新建 菜单命令, 显示出 新建 对话框 单击 工程 标签, 从列表框中选中 MFC AppWizard(exe) 项, 单击 位置 编辑框右侧的浏览按钮, 从弹出的 选择目录 对话框指定项目所在的文件夹 D:\Visual C++ 程序 \LiMing\3 在 工程名称 编辑框中输入项目名 Ex_Cal, 结果如图 3.2 所示 图 3.2 创建项目 Ex_Cal (2) 单击按钮进入下一步, 出现向导的步骤 1( 共 1 步 ) 对话框, 选定 基本对话框 (Dialog Based, 基于对话框 ) 类型 单击按钮, 出现一个信息对话框, 显

实验 3 常用控件 55 示出用户在前面几个步骤中做出的选择, 单击按钮, 系统开始创建, 并又回到了 Visual C++ 6.0 的主界面, 同时自动打开对话框模板编辑器以及控件工具栏 控件布局工具栏等 (3) 删除对话框模板中的 TODO:xx 静态控件以及 确定 和 取消 按钮 ; 将对话框标题设为 简单计算器, 字体设为 Tahoma,8 (4) 单击布局工具栏上的按钮, 打开对话框模板的网格 调整对话框的大小, 参看图 3.1 的控件布局为对话框添加如表 3.1 所示的一些控件 需要说明的是, 表中控件 ID 号中的 = 用来重新为其指定一个值 例如,IDC_BUTTON_0 = 600 表示将按钮 ID 号 IDC_ BUTTON_0 的值设为 600 表 3.1 简单计算器对话框添加的控件 添加的控件 ID 号 标题 其他属性 静态文本 IDC_STATIC_DISP 默认 靠右, 垂直居中, 凹陷 按钮 IDC_BUTTON_7=607 7 默认 按钮 IDC_BUTTON_8=608 8 默认 按钮 IDC_BUTTON_9=609 9 默认 按钮 IDC_BUTTON_4=604 4 默认 按钮 IDC_BUTTON_5=605 5 默认 按钮 IDC_BUTTON_6=606 6 默认 按钮 IDC_BUTTON_1=601 1 默认 按钮 IDC_BUTTON_2=602 2 默认 按钮 IDC_BUTTON_3=603 3 默认 按钮 IDC_BUTTON_0=600 0 默认 按钮 IDC_BUTTON_00=599 00 默认 按钮 IDC_BUTTON_DOT. 默认 按钮 IDC_BUTTON_BACK 默认 按钮 IDC_BUTTON_CLEAR C 默认 按钮 IDC_BUTTON_MUL=701 x 默认 按钮 IDC_BUTTON_DIV=702 默认 按钮 IDC_BUTTON_ADD=703 + 默认 按钮 IDC_BUTTON_SUB=704 - 默认 按钮 IDC_BUTTON_RES = 默认 图 3.3 资源符号对话框 图 3.4 设置控件 Tab 顺序

56 Visual C++ 实训 ( 第 3 版 ) (5) 选择 查看 资源符号 菜单命令, 弹出如图 3.3 所示的 资源符号 对话框, 从中核对它们的值是否与表 3.1 所设一致 (6) 关闭 资源符号 对话框 选择 布局 Tab 顺序 菜单或直接按快捷键 Ctrl+D, 则对话框模板中添加的各控件旁出现蓝底白字的数字, 这个数字就是表示该控件在使用 Tab 键选择时的次序, 如图 3.4 所示 单击 = 按钮, 则其 Tab 顺序值被重置为 1, 这就意味着该控件在对话框显示第 1 个被选定的对象 按 Enter 键或在其他区域单击鼠标, 退出 Tab 顺序设置状态 (7) 按 Ctrl+W 快捷键, 弹出 MFC ClassWizard 对话框, 切换到 Member Variables 页面, 查看 Class name 是否是 CEx_CalDlg, 然后选中 IDC_STATIC_DISP, 双击鼠标或单击 Add Variables 按钮, 为其设定 Value 类别的 CString 类型变量 m_strdisp 单击按钮, 退出 MFC ClassWizard 对话框, 回到 Visual C++ 6.0 主界面 (8) 编译并运行 3.1.2 映射并控制输入对于按钮等控件来说, 可通过映射 WM_COMMAND 消息 ( 重载 OnCommand) 达到统一处理消息的目的 为了区分简单计算器中 0 00 1~9 数字按钮与小数点 加减乘除等按钮, 这里用成员变量 m_ncurkeytype( 当前按钮类型 ) m_bhasdot( 是否已有小数点 ) m_bhasnum( 是否已有非 0 数值 ) 来控制输入 具体步骤如下 : ( 1 ) 将项目工作区窗口切换到 ClassView 页面, 双击节点, 打开 Ex_CalDlg.h, 在类 CEx_CalDlg 中添加下列成员变量定义代码 : class CEx_CalDlg : public CDialog public: int m_ncurkeytype; bool m_bhasdot; bool m_bhasnum; // Construction public: CEx_CalDlg(CWnd* pparent = NULL); ; // standard constructor (2) 在项目工作区窗口的 ClassView 页面中, 将节点展开, 双击成员函数节点, 在 OnInitDialog 函数的最后 (return true; 语句前 ) 添加下列初始化代码 : BOOL CEx_CalDlg::OnInitDialog() CDialog::OnInitDialog(); // TODO: Add extra initialization here m_strdisp = "0"; // 开始显示为 0

实验 3 常用控件 57 m_bhasdot = false; m_bhasnum = false; m_ncurkeytype = -1; // 没有输入 // 设置显示字体 CWnd* pwnd = GetDlgItem( IDC_STATIC_DISP ); CFont* pfont = pwnd->getfont(); LOGFONT lf; pfont->getlogfont( &lf ); lf.lfheight = -24; // 指定为 24 像素高度 static CFont font; // 须将其指定为全局, 否则后面的字体设置无效 font.createfontindirect(&lf); pwnd->setfont( &font ); // 创建字体 UpdateData( false ); return TRUE; // return TRUE unless you set the focus to a control (3) 编译并运行 (4) 按 Ctrl+W 快捷键, 弹出 MFC ClassWizard 对话框, 切换到 Message Maps 页面, 查看 Class name 是否是 CEx_CalDlg, 然后在 Object IDs 框中选中 CEx_CalDlg, 在 Messages 框中找到并双击 OnCommand 这样,OnCommand 消息函数就添加好了 (5) 单击按钮, 退出 MFC ClassWizard 对话框并自动定位到 OnCommand 消息函数的实现代码处, 添加下列代码 : BOOL CEx_CalDlg::OnCommand(WPARAM wparam, LPARAM lparam) // TODO: Add your specialized code here and/or call the base class WORD nid = LOWORD( wparam ); // 获取控件 ID if (( nid >= 599 ) && ( nid <= 609 )) // 数字按钮 // 处理 0 00 按钮 if (( nid == 600 ) ( nid == 599 )) if ( m_bhasdot m_bhasnum ) // 有小数点或非 0 数值 m_strdisp = m_strdisp + "0"; if ( nid == 599 ) m_strdisp = m_strdisp + "0"; else UpdateData( false ); m_ncurkeytype = 1;

58 Visual C++ 实训 ( 第 3 版 ) if ( m_ncurkeytype < 0 ) m_strdisp.empty(); m_bhasnum = true; CString strnum; strnum.format("%d", nid - 600 ); m_strdisp = m_strdisp + strnum; UpdateData( false ); m_ncurkeytype = 1; else if ( nid == IDC_BUTTON_DOT ) if (!m_bhasdot ) m_bhasdot = true; m_strdisp = m_strdisp + "."; // 处理小数点按钮 UpdateData( false ); m_ncurkeytype = 2; else if (( nid >= 701 ) && ( nid <= 704 )) // 处理 * / + - int nlength = m_strdisp.getlength(); if (( m_ncurkeytype > 0 ) && ( nlength > 0 )) m_strdisp.replace( " ", "*" ); m_strdisp.replace( " ", "/" ); CString strop[] = "*", "/", "+", "-"; if ( m_ncurkeytype >= 5 ) nlength = m_strdisp.getlength(); m_strdisp = m_strdisp.left( nlength - 1 ); m_strdisp = m_strdisp + strop[ nid - 701 ]; m_strdisp.replace( "*", " " ); m_strdisp.replace( "/", " " ); UpdateData( false ); m_ncurkeytype = 5; m_bhasdot = false; m_bhasnum = false;

实验 3 常用控件 59 return CDialog::OnCommand(wParam, lparam); (6) 按 Ctrl+W 快捷键, 打开 MFC ClassWizard 对话框, 在 Object IDs 框中选中 IDC_BUTTON_CLEAR, 在 Messages 框中找到并双击 BN_CLICKED, 弹出 Add Member Function 对话框, 保留默认的函数名 OnButtonClear, 单击 按钮 (7) 在 Member functions 列表中, 双击消息函数 OnButtonClear 或单击 按钮, 退出 MFC ClassWizard 对话框, 并转向文档窗口, 自动定位到 CEx_CalDlg:: OnButtonClear 函数实现的源代码处, 添加下列代码 : void CEx_CalDlg::OnButtonClear() // TODO: Add your control notification handler code here m_strdisp = "0"; // 开始显示为 0 m_bhasdot = false; m_bhasnum = false; m_ncurkeytype = -1; // 没有输入 UpdateData( false ); (8) 类似地, 用 MFC ClassWizard 为按钮 IDC_BUTTON_BACK 添加 BN_CLICKED 消息映射函数 OnButtonBack, 并添加下列代码 : void CEx_CalDlg::OnButtonBack() // TODO: Add your control notification handler code here if ( m_ncurkeytype < 0 ) return; m_strdisp.replace( " ", "*" ); m_strdisp.replace( " ", "/" ); int nlength = m_strdisp.getlength(); if ( nlength <= 1 ) OnButtonClear(); // 则相当于按 C 按钮 return; m_strdisp = m_strdisp.left( nlength - 1 ); char chlast = m_strdisp[ nlength - 2 ]; if (( chlast >= '0' ) && ( chlast <= '9' ))

60 Visual C++ 实训 ( 第 3 版 ) m_bhasnum = true; m_ncurkeytype = 1; else if ( chlast == '.' ) m_bhasdot = true; m_ncurkeytype = 2; else // 剩下来应是 + - * / 运算符号 m_ncurkeytype = 5; m_bhasdot = false; m_bhasnum = false; m_strdisp.replace( "*", " " ); m_strdisp.replace( "/", " " ); UpdateData( false ); (9) 编译运行并测试, 结果如前图 3.1(a) 所示 3.1.3 解析并输出结果由于乘除的运算等级要高于加减, 因此解析输入的表达式时需要先按乘除进行运算 由于乘除是二元运算符, 因此可先找出运算符左 右两边操作数, 运算后的结果 替换 原来的表达式, 然后循环解析直到没有乘除运算符为止, 最后解析 加减 运算 同级别相邻运算符需按从左到右的顺序来计算结果 具体步骤如下 : (1) 将项目工作区窗口切换到 ClassView 页面, 右击节点, 从弹出的快捷菜单中选择 ( 添加成员函数 ) 命令, 弹出如图 3.5 所示的对话框 在函数类型 (Function Type) 框中输入 CString, 在函数声明 (Function Declaration) 框中输入 GetLeftData(CString str, double& fres), 对话框下方用来确定该成员函数的访问方式 图 3.5 添加成员函数 对话框

实验 3 常用控件 61 (2) 保留默认的 Public 访问类型, 单击按钮, 退出对话框, 并自动定位到添加的函数实现代码处, 在这里可以为该函数添加下列代码 : // 取运算符左侧的操作数, 结果保存到引用 fres 中, 剩下的字符串由函数返回 CString CEx_CalDlg::GetLeftData(CString str, double&fres) int nindex = str.getlength() - 1; // 从最后往前查找 while ( nindex >= 0 ) char ch = str[ nindex ]; if (( ch == '+' ) ( ch == '-' ) ( ch == '*' ) ( ch == '/' )) break; nindex--; CString strleft; // 数据拿掉后还剩下的字符串 if ( nindex >= 0 ) strleft = str.left( nindex + 1 ); fres = atof( str.mid( nindex + 1 ) ); else fres = atof( str ); strleft.empty(); return strleft; (3) 类似地, 为 CEx_CalDlg 类添加成员函数 GetRightData, 用来取运算符右侧的操作数, 结果保存到引用 fres 中, 剩下的字符串由函数返回 添加的函数代码如下 : // 取运算符左侧的操作数, 结果保存到引用 fres 中, 剩下的字符串由函数返回 CString CEx_CalDlg::GetRightData(CString str, double&fres) int nindex = 0; int nlength = str.getlength(); while ( nindex < nlength ) char ch = str[ nindex ]; if (( ch == '+' ) ( ch == '-' ) ( ch == '*' ) ( ch == '/' )) break; nindex++;

62 Visual C++ 实训 ( 第 3 版 ) CString strleft; // 数据拿掉后还剩下的字符串 if ( nindex >= 0 ) strleft = str.mid( nindex ); fres = atof( str.left( nindex ) ); else fres = atof( str ); strleft.empty(); return strleft; (4) 为 CEx_CalDlg 类添加用于处理运算符的成员函数 DoParseOP, 函数返用解析后 的字符串 具体的函数代码如下 : CString CEx_CalDlg::DoParseOP(CString strdata, CString strop) int npos; while (( npos = strdata.findoneof( strop ) ) >= 0 ) // 处理首字符是运算符的情况 if ( npos == 0 ) CString strtemp = strdata.mid( 1 ); npos = strtemp.findoneof( strop ); if ( npos < 0 ) break; else npos++; char chop = strdata[npos]; // 以当前运算符为界, 将字符串分成左 右两段 CString strl = strdata.left( npos ); CString strr = strdata.mid( npos + 1 ); double fldata, frdata, fdata; CString strll = GetLeftData( strl, fldata ); CString strrr = GetRightData( strr, frdata ); if ( chop == '*' ) else if ( chop == '/' ) else if ( chop == '+' ) else if ( chop == '-' ) fdata = fldata * frdata; fdata = fldata / frdata; fdata = fldata + frdata; fdata = fldata - frdata;

实验 3 常用控件 63 CString strres; strres.format("%f", fdata ); strres.trimright('0'); strres.trimright('.'); // 将左右剩下来和当前计算结果合成一个表达式 strdata.format("%s%s%s", strll, strres, strrr ); return strdata; (5) 打开 MFC ClassWizard 对话框, 添加按钮 IDC_BUTTON_CLEAR 的 BN_CLICKED 消息处理函数 CEx_CalDlg::OnButtonRes, 并添加下列代码 : void CEx_CalDlg::OnButtonRes() // TODO: Add your control notification handler code here // 无输入或输入为空 if (( m_ncurkeytype < 0 ) ( m_strdisp.isempty() )) OnButtonClear(); return; m_strdisp.replace( " ", "*" ); m_strdisp.replace( " ", "/" ); // 先处理 */, 再处理 +- m_strdisp = DoParseOP( m_strdisp, "*/" ); m_strdisp = DoParseOP( m_strdisp, "+-" ); // 处理结果 m_strdisp.trimright('0'); m_strdisp.trimright('.'); UpdateData( false ); m_bhasnum = true; if ( m_strdisp.find( '.' ) >= 0 ) m_bhasdot = true; else m_bhasdot = false; m_ncurkeytype = 1; (6) 编译运行并测试, 结果如前面图 3.1 所示

64 Visual C++ 实训 ( 第 3 版 ) 3.2 控件图案绘制 在控件中绘制图案的关键在于控制对话框自动刷新控件 图案绘制后还可通过 图案 组合框和颜色分量调节器来改变绘制的图案类型和颜色, 创建的项目为 Ex_Hatch, 结果如图 3.6(a) 所示 (a) (b) 图 3.6 Ex_Hatch 运行结果具体的实验 ( 实训 ) 过程如下 : 设计图案绘制对话框 WM_PAINT 和控件绘制 图案及其颜色调整 3.2.1 设计图案绘制对话框具体步骤如下 : (1) 选择 文件 关闭工作区 菜单命令, 将弹出一个提示对话框, 询问是否真的关闭所有文档窗口 单击按钮, 关闭原来的项目 (2) 选择 文件 新建 菜单命令, 弹出 新建 对话框, 在 工程 页面的列表框中选定 MFC AppWizard(exe) 项, 在 工程名称 编辑框中输入项目名 Ex_Hatch (3) 单击按钮进入下一步, 出现向导的步骤 1( 共 1 步 ) 对话框, 选定 基本对话框 (Dialog Based, 基于对话框的应用程序, 简称对话框 ) 类型 单击按钮, 出现一个信息对话框, 单击按钮, 系统开始创建, 并又回到了 Visual C++ 6.0 的主界面, 同时还自动打开对话框模板编辑器以及控件工具栏 控件布局工具栏等 (4) 删除对话框模板中的 TODO:xx 静态控件和 确定 按钮 ; 将对话框标题设为 图案绘制 ; 将 取消 按钮标题改为 退出 (5) 单击布局工具栏上的按钮, 打开对话框模板的网格 调整对话框大小, 并将 退出 按钮移至对话框的右下角 参看图 3.6(b) 控件布局为对话框添加如表 3.2 所示的一些控件

实验 3 常用控件 65 表 3.2 图案绘制对话框添加的控件 添加的控件 ID 号标题其他属性 组合框 IDC_COMBO_HATCH 默认 静态文本 IDC_STATIC_DRAW 默认 Static edge( 静态边缘 ), 其余默认 编辑框 IDC_EDIT_R 默认 上下旋转控件 IDC_SPIN_R Auto buddy( 自动结伴 ),Set buddy integer ( 设置结伴整数 ),Right( 靠右 ) 对齐 滚动条 IDC_SCROLLBAR_G 默认 滑动条 IDC_SLIDER_B 点 : 两者, 打勾标记 自动打勾, 其余 需要说明的是 : 当添加组合框后, 一定要单击右侧的下拉箭头, 增大下拉框的大小 当 红色分量 编辑框添加之后, 紧接着要添加上下旋转按钮, 这样它们才能组成 伙伴窗口 (6) 按 Ctrl+W 快捷键, 弹出 MFC ClassWizard 对话框, 切换到 Member Variables 页 面, 查看 Class name 是否是 CEx_HatchDlg, 然后选中所需的控件 ID 号, 双击鼠标或单击 Add Variables 按钮, 依次为表 3.3 中的控件增加成员相应的控件变量 表 3.3 控件变量 控件 ID 号 变量类别 变量类型 变量名 范围和大小 IDC_COMBO_HATCH Control CComboBox m_cbhatch IDC_EDIT_R Value UINT m_nrvalue 0~255 IDC_SPIN_R Control CSpinButtonCtrl m_spinrvalue IDC_SCROLLBAR_G Control ScrollBar m_sbgvalue IDC_SLIDER_B Control CSliderCtrl m_sdbvalue (7) 单击按钮, 退出 MFC ClassWizard 对话框, 回到 Visual C++ 6.0 的主界面, 编译并运行 3.2.2 WM_PAINT 和控件绘制在 MFC 框架中, 当需要更新或重新绘制窗口的外观时, 应用程序就会发送 WM_PAINT 消息, 通常需要在对话框中映射 WM_PAINT 消息以便执行自己的绘制代码 不过, 基于对话框应用程序中,WM_PAINT 消息映射已自动添加 所以, 控件绘制的代码只要添加到 OnPaint 映射函数就可以了 只是, 在对话框中的控件进行绘画时, 为了防止 Windows 用系统默认的颜色向对话框进行重复绘制, 用户须调用 UpdateWindow( 更新窗口 ) 函数来达到这一效果 UpdateWindow 是 CWnd 的一个无参数的成员函数, 其目的是绕过系统的消息队列, 而直接发送或停止发送 WM_PAINT 消息 当窗口没有需要更新的区域时, 就停止发送 这样, 当用户绘制完图形时, 由于没有 WM_PAINT 消息的发送, 系统也就不会用默认的颜色对窗口进行重复绘制

66 Visual C++ 实训 ( 第 3 版 ) 当然, 也可在程序中通过调用 Invalidate 函数来通知系统此时的窗口状态已变为无效, 强制系统调用 WM_PAINT 消息函数 OnPaint 重新绘制 具体步骤如下 : (1) 将项目工作区窗口切换到 ClassView 页面, 展开 Ex_Hatch 中的所有节点 双击 节点, 从弹出的快捷菜单中选择 ( 添加成员变量 ), 弹出 添加成员变量 对话框 (2) 在 变量类型 框中输入 UINT( 无符号整数 ), 在 变量名称 框中输入变量名 m_ngvalue, 保留默认的成员属性, 单击按钮 类似的, 添加下列成员变量 : class CEx_HatchDlg : public CDialog // Construction public: UINT m_ngvalue; UINT m_nbvalue; UINT m_nhatch; CEx_HatchDlg(CWnd* pparent = NULL); // standard constructor (3) 再次双击节点, 从弹出的快捷菜单中选择 ( 添加成员函数 ), 在弹出的对话框中为 CEx_HatchDlg 类添加函数 void DrawHatch(void), 单击 按钮, 添加下列函数实现代码 : void CEx_HatchDlg::DrawHatch() CWnd* pwnd = GetDlgItem(IDC_STATIC_DRAW); pwnd->updatewindow(); CDC* pdc = pwnd->getdc(); CBrush drawbrush; // 获得窗口当前的设备环境指针 // 定义画刷变量 drawbrush.createhatchbrush( m_nhatch, RGB(m_nRValue,m_nGValue, m_nbvalue)); // 创建一个图案画刷 RGB 是一个颜色宏, 用来将指定的红 绿 蓝 3 种颜色分量 // 转换成一个 32 位的 RGB 颜色值 CBrush* poldbrush = pdc->selectobject(&drawbrush); CRect rcclient; pwnd->getclientrect(rcclient); pdc->rectangle(rcclient); pdc->selectobject(poldbrush); // 获取当前控件的客房区大小 // 用当前画刷填充指定的矩形框 // 恢复原来的画刷 (4) 在 CEx_HatchDlg::OnInitDialog 函数中添加下列初始化代码 : BOOL CEx_HatchDlg::OnInitDialog()

实验 3 常用控件 67 // TODO: Add extra initialization here // 填充并设定图案组合框选项 int nindex; nindex = m_cbhatch.addstring( " 向上 45 度斜线 " ); m_cbhatch.setitemdata( nindex, HS_BDIAGONAL ); nindex = m_cbhatch.addstring( " 交叉十字线 " ); m_cbhatch.setitemdata( nindex, HS_CROSS ); nindex = m_cbhatch.addstring( " 斜十字交叉线 " ); m_cbhatch.setitemdata( nindex, HS_DIAGCROSS ); nindex = m_cbhatch.addstring( " 向下 45 度斜线 " ); m_cbhatch.setitemdata( nindex, HS_FDIAGONAL ); nindex = m_cbhatch.addstring( " 水平线 " ); m_cbhatch.setitemdata( nindex, HS_HORIZONTAL ); nindex = m_cbhatch.addstring( " 垂直线 " ); m_cbhatch.setitemdata( nindex, HS_VERTICAL ); m_cbhatch.setcursel( 0 ); m_nhatch = m_cbhatch.getitemdata( 0 ); // 设置上下转换按钮范围和当前值 m_spinrvalue.setrange( 0, 255 ); m_nrvalue = 0; m_spinrvalue.setpos( m_nrvalue ); // 设置滚动条范围和当前值 m_sbgvalue.setscrollrange( 0, 255 ); m_ngvalue = 0; m_sbgvalue.setscrollpos( m_ngvalue ); // 设置滑动条范围和当前值 m_sdbvalue.setrange( 0, 255 ); m_nbvalue = 0; m_sdbvalue.setpos( m_nbvalue ); return TRUE; // return TRUE unless you set the focus to a control (5) 在 CEx_HatchDlg::OnPaint 函数中添加下列代码 : void CEx_HatchDlg::OnPaint() if (IsIconic()) else CDialog::OnPaint(); DrawHatch(); (6) 编译并运行, 结果如图 3.7 所示

68 Visual C++ 实训 ( 第 3 版 ) 图 3.7 Ex_Hatch 第一次运行 3.2.3 图案及其颜色调整具体步骤如下 : (1) 用 MFC ClassWizard 为 CEx_HatchDlg 类映射组合框 IDC_COMBO_HATCH 的 CB_SELCHANGE 消息, 保留默认的消息映射函数名, 添加下列代码 : void CEx_HatchDlg::OnSelchangeComboHatch() // TODO: Add your control notification handler code here int nindex = m_cbhatch.getcursel(); if ( nindex!= CB_ERR ) m_nhatch = m_cbhatch.getitemdata( nindex ); DrawHatch(); (2) 为 CEx_HatchDlg 类添加一个 BOOL m_bok 成员变量, 同时在 CEx_HatchDlg 的构造函数中令其初值为 FALSE, 即 : CEx_HatchDlg::CEx_HatchDlg(CWnd* pparent /*=NULL*/) : CDialog(CEx_HatchDlg::IDD, pparent) m_hicon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); m_bok = FALSE; (3) 在 CEx_HatchDlg::OnInitDialog 函数的最后 return 语句之前, 添加下列代码 : m_bok = TRUE; (4) 用 MFC ClassWizard 为 CEx_HatchDlg 类映射编辑框 IDC_EDIT_R 的 EN_

实验 3 常用控件 69 CHANGE 消息, 保留默认的消息映射函数名, 添加下列代码 : void CEx_HatchDlg::OnChangeEditR() // TODO: Add your control notification handler code here if ( m_bok ) UpdateData(); DrawHatch(); 需要说明的是, 由于编辑框和上下旋转按钮控件结成伙伴窗口时, 任何对上下旋转按钮的初始化操作均影响结伴的编辑框的控件变量的值无效, 从而产生断言错误 ( 发生在 DLGDATA.CPP 文件的第 624 行 ) 在代码引入 m_bok 可解决这个错误 (5) 用 MFC ClassWizard 为 CEx_HatchDlg 类映射 WM_HSCROLL 消息, 在映射函数中添加下列代码 : void CEx_HatchDlg::OnHScroll(UINT nsbcode, UINT npos, CScrollBar* pscrollbar) // TODO: Add your message handler code here and/or call default int nid = pscrollbar->getdlgctrlid(); if (nid == IDC_SLIDER_B) // 若是滑动条产生水平滚动消息 m_nbvalue = m_sdbvalue.getpos(); // 则获得滑动条当前的位置 DrawHatch(); if (nid == IDC_SCROLLBAR_G) // 若是滚动条产生水平滚动消息 switch(nsbcode) case SB_LINELEFT: m_ngvalue--; // 单击滚动条左边箭头 break; case SB_LINERIGHT: m_ngvalue++; // 单击滚动条右边箭头 break; case SB_PAGELEFT: m_ngvalue -= 10; break; case SB_PAGERIGHT: m_ngvalue += 10; break; case SB_THUMBTRACK: m_ngvalue = npos; break; if (m_ngvalue<0) m_ngvalue = 0; if (m_ngvalue>255) m_ngvalue = 255;

70 Visual C++ 实训 ( 第 3 版 ) m_sbgvalue.setscrollpos(m_ngvalue); DrawHatch(); CDialog::OnHScroll(nSBCode, npos, pscrollbar); (6) 编译运行并测试, 结果如图 3.6(a) 所示 3.3 管理学生的个人信息 设计一个学生个人信息管理对话框应用程序 Ex_Person, 如图 3.8(a) 所示 单击按钮, 弹出 学生个人信息 对话框, 如图 3.8(b) 所示, 从中可以填写姓名 学号 性别 出生 ( 日期 ) 电话 地址等信息, 填完后, 单击按钮, 信息添加到列表控件中 单击按钮, 则仍弹出图 3.8(b) 的对话框, 单击按钮, 当前信息被修改 单击按钮, 则删除该记录 需要说明的是, 当列表框没有记录或没有选定的记录项, 则和按钮是灰显的 (a) (b) 图 3.8 Ex_Person 运行结果具体的实验 ( 实训 ) 过程如下 : 设计主对话框 添加并设计个人信息对话框 完善个人信息操作 3.3.1 设计主对话框具体步骤如下 : (1) 选择 文件 关闭工作区 菜单命令, 将弹出一个提示对话框, 询问是否真的关闭所有文档窗口 单击按钮, 关闭原来的项目 (2) 选择 文件 新建 菜单命令, 弹出 新建 对话框, 在 工程 页面的列表框中选定 MFC AppWizard(exe) 项, 在 工程名称 编辑框中输入项目名 Ex_Person

实验 3 常用控件 71 (3) 单击按钮进入下一步, 出现向导的步骤 1( 共 1 步 ) 对话框, 选定 基本对话框 (Dialog Based, 基于对话框的应用程序, 简称对话框 ) 类型, 单击按钮, 出现一个信息对话框, 单击按钮, 系统开始创建, 并又回到了 Visual C++ 6.0 的主界面, 同时还自动打开对话框模板编辑器以及控件工具栏 控件布局工具栏等 (4) 删除对话框模板中的 TODO:xx 静态控件和 确定 按钮 ; 将对话框标题设为 学生个人信息管理 ; 将 取消 按钮标题改为 退出 (5) 单击布局工具栏上的按钮, 打开对话框模板的网格 调整对话框的大小, 并将 退出 按钮移至对话框的右下角 参看图 3.8(a) 控件布局添加如表 3.5 所示的一些控件 表 3.5 主对话框添加的控件 添加的控件 ID 号标题其他属性 列表控件 IDC_LIST1 报告 (Report), 其余默认 按钮 IDC_BUTTON_ADD 添加 默认 按钮 IDC_BUTTON_CHAN 修改 默认 按钮 IDC_BUTTON_DEL 删除 默认 (6) 按 Ctrl+W 快捷键, 弹出 MFC ClassWizard 对话框, 切换到 Member Variables 页面, 查看 Class name 是否是 CEx_PersonDlg, 然后选中 IDC_LIST1, 双击鼠标或单击 Add Variables 按钮, 为对话框添加 Control 类别的 CListCtrl 类型的控件变量 m_datalist 单击 按钮, 退出 MFC ClassWizard 对话框, 回到 Visual C++ 6.0 的主界面, 编译并运行 3.3.2 添加并设计个人信息对话框 具体步骤如下 : (1) 选择 插入 资源 菜单, 或按快捷键 Ctrl+R 打开 插入资源 对话框, 在 对话框中可以看到资源列表中存在 Dialog 项 选中 Dialog, 单击 按钮, 系统就会 自动为当前应用程序添加一个对话框资源 (2) 保留默认的对话框资源 ID 号, 在对话框资源模板的空白区域 ( 没有其他元素或 控件 ) 内双击鼠标, 将弹出 Adding a Class 对话框, 询问是否为对话框资源创建一个新类 单击 按钮, 出现 New Class( 新类 ) 对话框 在 Name 框中输入类名 COneDlg, 单 击 按钮 这样, 一个基于对话框资源模板 IDD_DIALOG1 的用户对话框类 COneDlg 就创建好了 然后, 回到 MFC ClassWizard(MFC 类向导 ) 对话框界面 单击 按 钮, 退出 MFC ClassWizard 对话框 (3) 将添加的对话框的标题设为 学生个人信息, 将对话框字体改为 宋体,9 号 将 OK 和 Cancel 按钮标题分别改为 确定 和 取消 单击布局工具栏上的 按钮, 打 开对话框模板的网格 调整对话框的大小, 将 和 按钮移至对话框的下方, 参看图 3.8(b) 控件布局添加如表 3.6 所示的一些控件 表 3.6 个人信息对话框添加的控件 添加的控件 ID 号标题其他属性 编辑框 ( 姓名 ) IDC EDIT NAME 默认 编辑框 ( 学号 ) IDC_EDIT_NO 默认

72 Visual C++ 实训 ( 第 3 版 ) 续表 添加的控件 ID 号标题其他属性 单选按钮 ( 男 ) IDC RADIO MALE 男 默认 单选按钮 ( 女 ) IDC_RADIO_FEMALE 女 默认 日期时间控件 IDC_DATETIMEPICKER1 默认 编辑框 ( 电话 ) IDC_EDIT_PHONE 默认 编辑框 ( 地址 ) IDC_EDIT_ADDRESS 多行, 其余默认 (4) 按 Ctrl+W 快捷键, 弹出 MFC ClassWizard 对话框, 切换到 Member Variables 页面, 查看 Class name 是否是 COneDlg, 然后选中所需的控件 ID 号, 双击鼠标或单击 Add Variables 按钮, 依次为表 3.7 中的控件增加成员相应的控件变量 表 3.7 控件变量 控件 ID 号 变量类别 变量类型 变量名 范围和大小 IDC_EDIT_NAME Value CString m_strname 20 IDC_EDIT_NO Value CString m_strno 20 IDC_DATETIMEPICKER1 Value CTime m_tbirth IDC_EDIT_PHONE Value CString m_strphone 25 IDC_EDIT_ADDRESS Value CString m_straddress 150 (5) 为 COneDlg 类添加一个 BOOL 型成员变量 m_bmale, 并在 COneDlg 类构造函数处设置该变量的初始值 : COneDlg::COneDlg(CWnd* pparent /*=NULL*/) : CDialog(COneDlg::IDD, pparent) //AFX_DATA_INIT(COneDlg) //AFX_DATA_INIT m_bmale = TRUE; (6) 用 MFC ClassWizard 为 COneDlg 添加 WM_INITDIALOG 消息映射, 并添加下列初始化代码 : BOOL COneDlg::OnInitDialog() CDialog::OnInitDialog(); // TODO: Add extra initialization here // 设置单选按钮初始选中状态 if (!m_bmale) CheckRadioButton(IDC_RADIO_MALE, IDC_RADIO_FEMALE, IDC_RADIO_ FEMALE); else CheckRadioButton(IDC_RADIO_MALE, IDC_RADIO_FEMALE, IDC_RADIO_

实验 3 常用控件 73 MALE); UpdateData( FALSE ); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE ( 7 ) 用 MFC ClassWizard 为 COneDlg 的单选按钮 IDC_RADIO_MALE 和 IDC_RADIO_FEMALE 分别添加 BN_CLICKED 消息的映射, 保留默认的映射函数名, 并添加下列代码 : void COneDlg::OnRadioMale() // TODO: Add your control notification handler code here m_bmale = TRUE; void COneDlg::OnRadioFemale() // TODO: Add your control notification handler code here m_bmale = FALSE; (8) 用 MFC ClassWizard 为 COneDlg 的按钮添加 BN_CLICKED 的消息映射, 保留默认的映射函数名, 并添加下列代码 : void COneDlg::OnOK() // TODO: Add extra validation here UpdateData(); m_strname.trimleft(); m_strno.trimleft(); if (m_strname.isempty()) MessageBox(" 必须要有姓名!"); else if (m_strno.isempty()) MessageBox(" 必须要有学号!"); else CDialog::OnOK(); (9) 编译并运行 3.3.3 完善个人信息操作具体步骤如下 : (1) 在 CEx_PersonDlg::OnInitDialog 函数中添加设置列表控件标题头代码以及按钮的初始状态 : BOOL CEx_PersonDlg::OnInitDialog()

74 Visual C++ 实训 ( 第 3 版 ) // TODO: Add extra initialization here // 创建列表控件的标题头 CString strheader[]= " 姓名 ", " 学号 ", " 性别 ", " 出生日期 ", " 联系电话 ", " 联系地址 "; int nheaderwidth[]= 80, 80, 40, 100, 100, 200 ; for (int ncol=0; ncol<6; ncol++) m_datalist.insertcolumn(ncol,strheader[ncol], LVCFMT_LEFT, nheaderwidth[ncol]); GetDlgItem( IDC_BUTTON_CHANGE )->EnableWindow(FALSE); GetDlgItem( IDC_BUTTON_DEL )->EnableWindow(FALSE); return TRUE; // return TRUE unless you set the focus to a control ( 2 ) 用 MFC ClassWizard 为 CEx_PersonDlg 的按钮 IDC_BUTTON_ADD 添加 BN_CLICKED 的消息映射, 保留默认的映射函数名, 并添加下列代码 : void CEx_PersonDlg::OnButtonAdd() // TODO: Add your control notification handler code here COneDlg dlg; if (IDOK!= dlg.domodal()) return; // 根据学号来判断学生基本信息是不是已经添加过 LVFINDINFO info; info.flags = LVFI_PARTIAL LVFI_STRING; info.psz = dlg.m_strno; if (m_datalist.finditem( &info )!= -1) // 若找到 CString str; str.format(" 学号为 %s 的学生个人信息已添加过!", dlg.m_strno); MessageBox(str); return; // 添加学生基本信息 int nindex = m_datalist.insertitem(m_datalist.getitemcount(), dlg. m_strname); m_datalist.setitemtext( nindex, 1, dlg.m_strno ); if (dlg.m_bmale) m_datalist.setitemtext( nindex, 2, " 男 " ); else m_datalist.setitemtext( nindex, 2, " 女 " ); m_datalist.setitemtext( nindex, 3, dlg.m_tbirth.format("%y-%m-%d") ); m_datalist.setitemtext( nindex, 4, dlg.m_strphone );

实验 3 常用控件 75 m_datalist.setitemtext( nindex, 5, dlg.m_straddress ); (3) 用 MFC ClassWizard 为 CEx_PersonDlg 的按钮 IDC_BUTTON_CHANGE 添加 BN_CLICKED 的消息映射, 保留默认的映射函数名, 并添加下列代码 : void CEx_PersonDlg::OnButtonChange() // TODO: Add your control notification handler code here // 获取被选择的列表项索引号 POSITION pos; pos = m_datalist.getfirstselecteditemposition(); if (pos == NULL) MessageBox(" 还没有选中列表项!"); return; int nitem = m_datalist.getnextselecteditem( pos ); COneDlg dlg; dlg.m_strname = m_datalist.getitemtext( nitem, 0 ); dlg.m_strno = m_datalist.getitemtext( nitem, 1 ); CString strmale = m_datalist.getitemtext( nitem, 2 ); strmale.trimleft(); strmale.trimright(); if ( strmale == " 男 " ) dlg.m_bmale = TRUE; else dlg.m_bmale = FALSE; CString strdate = m_datalist.getitemtext( nitem, 3 ); // 将文本转换成日期 COleDateTime odtdata; odtdata.parsedatetime( strdate, VAR_DATEVALUEONLY ); SYSTEMTIME systime; odtdata.getassystemtime( systime ); dlg.m_tbirth = CTime( systime ); dlg.m_strphone = m_datalist.getitemtext( nitem, 4 ); dlg.m_straddress= m_datalist.getitemtext( nitem, 5 ); if (IDOK!= dlg.domodal()) return; m_datalist.setitemtext( nitem, 0, dlg.m_strname); m_datalist.setitemtext( nitem, 1, dlg.m_strno ); if (dlg.m_bmale) m_datalist.setitemtext( nitem, 2, " 男 " ); else

76 Visual C++ 实训 ( 第 3 版 ) m_datalist.setitemtext( nitem, 2, " 女 " ); m_datalist.setitemtext( nitem, 3, dlg.m_tbirth.format("%y-%m-%d") ); m_datalist.setitemtext( nitem, 4, dlg.m_strphone ); m_datalist.setitemtext( nitem, 5, dlg.m_straddress ); ( 4 ) 用 MFC ClassWizard 为 CEx_PersonDlg 的按钮 IDC_BUTTON_DEL 添加 BN_CLICKED 的消息映射, 保留默认的映射函数名, 并添加下列代码 : void CEx_PersonDlg::OnButtonDel() // TODO: Add your control notification handler code here // 获取被选择的列表项索引号 POSITION pos; pos = m_datalist.getfirstselecteditemposition(); if (pos == NULL) MessageBox(" 还没有选中列表项!"); return; int nitem = m_datalist.getnextselecteditem( pos ); if ( IDYES == MessageBox( " 确实要删除吗?", " 警告 ", MB_ICONWARNING MB_YESNO ) ) m_datalist.deleteitem( nitem ); (5) 用 MFC ClassWizard 为 CEx_PersonDlg 的列表控件 IDC_LIST1 添加 LVN_ TEMCHANGED 的消息映射, 保留默认的映射函数名, 并添加下列代码 : void CEx_PersonDlg::OnItemchangedList1(NMHDR* pnmhdr, LRESULT* presult) NM_LISTVIEW * pnmlistview = (NM_LISTVIEW*)pNMHDR; // TODO: Add your control notification handler code here POSITION pos; pos = m_datalist.getfirstselecteditemposition(); if (pos == NULL) GetDlgItem( IDC_BUTTON_CHANGE )->EnableWindow(FALSE); GetDlgItem( IDC_BUTTON_DEL )->EnableWindow(FALSE); else GetDlgItem( IDC_BUTTON_CHANGE )->EnableWindow(TRUE); GetDlgItem( IDC_BUTTON_DEL )->EnableWindow(TRUE); *presult = 0;

实验 3 常用控件 77 (6) 在文件 Ex_PersonDlg.cpp 的前面添加 COneDlg 类的头文件包含命令 : #include "stdafx.h" #include "Ex_Person.h" #include "Ex_PersonDlg.h" #include "OneDlg.h" (7) 编译运行并测试 3.4 常见问题处理 (1) 如何将在项目工作区中消失的类找出来? 或者是有 类, 但双击成员函数节点却打不开其实现文件 (.cpp), 怎么办? 解答 : 打开该类对应的头文件, 然后将其类名随便改一下, 这个时候工作区就会出现新的类, 再将这个类改回原来的名字就可以了 或者, 关闭当前项目, 删除当前项目文件夹中的 *.ncb 文件, 然后再重新打开项目 或者, 删除当前项目文件夹中的 *.clw 文件, 然后按 Ctrl+W 快捷键, 会提示添加类, 添加全部 或者, 用 MFC ClassWizard 为这个类生成一个消息映射函数, 就可以在项目工作区的 ClassView 页面中看到了, 最后再删除添加的映射函数 (2) 数值与字符串如何相互转换? 解答 : 使用 atof atoi 和 atol 可将字符串转换成 double int 和 long 型数值 使用 CString 类的 Format 格式函数, 可使用 stdio.h 中的 sprintf 类的格式进行转换 (3) 如何遍历对话框中的某些控件? 解答 : 用 CWnd::GetWindow 和 CWnd::GetNextWindow 来完成, 如下面的代码是用来遍历所有编辑框控件 : void CSimParDlg::OnButton1() CWnd *pwnd; pwnd=getwindow(gw_child); while (pwnd!=null) if (pwnd-> IsKindOf(RUNTIME_CLASS(CEdit))) pwnd-> EnableWindow(false); pwnd=pwnd-> GetNextWindow();

78 Visual C++ 实训 ( 第 3 版 ) 3.5 思考与练习 (1) 在 简单计算器 对话框中若添加左括号 ( 和右括号 ) 按钮, 则如何实现? 对话框代码应如何修改? (2) 若在 学生个人信息 对话框中添加一个静态图片控件, 当单击性别 男 时, 图片呈现一个 男 图片 ( 可用其他图片代替 ), 而当单击性别 女 时, 图片是另一个内容 看看如何实现? (3) 如何使列表控件的报表视图带有网格, 且选择时是选定整个一行?