1.04k likes | 1.21k Views
第 六 章 对话框与控件. VC++ 实用教程. 河北经贸大学 信息技术学院 2008.9. 教学目标. ◆掌握常用控件的使用方法; ◆掌握模式对话框与非模式对话框的创建与使用; ◆了解通用对话框的使用方法; ◆了解系统的集成方法; ◆熟练掌握基于模式对话框的应用程序的编程方法和步骤。. 本章主要内容. 4.1 对话框概述 4.2 静态控件 4.3 编辑框 4.4 按钮类 4.5 列表框控件 4.6 列表视图( CListCtrl )控件 4.7 组合框 (CComboBox) 控件 4.8 滚动类控件
E N D
第六章对话框与控件 VC++实用教程 河北经贸大学 信息技术学院 2008.9
教学目标 • ◆掌握常用控件的使用方法; • ◆掌握模式对话框与非模式对话框的创建与使用; • ◆了解通用对话框的使用方法; • ◆了解系统的集成方法; • ◆熟练掌握基于模式对话框的应用程序的编程方法和步骤。
本章主要内容 4.1 对话框概述 4.2 静态控件 4.3 编辑框 4.4 按钮类 4.5 列表框控件 4.6 列表视图(CListCtrl)控件 4.7 组合框 (CComboBox)控件 4.8 滚动类控件 4.9 通用对话框和消息对话框 习题四 实验指导四
4.1 对话框概述 • 对话框 • 对话框编辑器 • 对话框编程 • 控件的创建与使用 • 访问控件
4.1.1 对话框 • 可视化的界面,包含:按钮、文本框、复选框等。 • 对话框是一个窗口,控件也是一个窗口 • 对话框的两种消息: WM_INITDIALOG:数据成员的初始化 WM_COMMAND:控件的消息 • MFC对对话框的支持:对话框从CDialog基类中派生一个类, MFC的CDialog类封装了用于对话框的显示、关闭等常用操作的许多功能函数;MFC程序框架;ClassWizard类向导 • 公共对话框: P103 表4-1 • 标准对话框控件 表4-2 • 用于对话框控件的 CWnd成员函数 表4-3 • 模式对话框和无模式对话框
对话框的类型 • 1.模式对话框 弹出后,用户必须作出相应得操作,否则不可以继续。 用途广。 • 2.无模式对话框 弹出后,一直保留在屏幕上,其他操作可继续,用的时候激活对话框即可。 两者的创建与显示方式不同: CPasswordDlg dlg1; Dlg1.DoModal();——模式 CPasswordDlg *pDlg; pDlg->Create(IDD_DIALOG1,this); pDlg->ShowWindow(true);——无模式 两者的终止函数不一样: Cdialog::EndDialog------模式 CWnd::DestroyWindow-----无模式 所占内存空间不同: 模式对话框: 由系统自动分配内存,当对话框退出时,对话框对象自动删除。 无模式对话框: 则需要用户来指定内存,退出时用户删除对话框对象
4.1.2 对话框编辑器 • 添加、选取、删除对话框控件; • 改变控件的Tab键次序; • 利用基准线、标尺及布局工具进行控件的布局; • 测试所编辑的对话框的性能。
4.1.3 对话框编程 • 1. 添加对话框资源 • 在单文档项目Ex4-1中,Insert-〉resourc(ctrl+R)-〉Dialog • 2. 编辑对话框属性 • 3. 向对话框内添加控件 • ——添加/选取/控件的布局/测试对话框 • 4. 使用ClassWizard,为对话框资源创建一个新类 CPasswordDialog • 为控件IDC_EDIT1关联成员变量 CStringm_Password • 5. 在程序(Ex4_1.cpp)中使用模式对话框 • #include "PasswordDialog.h“ • bool CEx4_1App ::InitInstance () • { …… • CPasswordDialog Dlg; //声明CPasswordDialog类的对象 • if ( Dlg.DoModal() != IDOK ) return false; //用户按下的不是"确认"按钮 • if ( Dlg.m_Password != "123456" ) //口令设为字符串"123456" • { • AfxMessageBox("口令错误,确认后将退出程序"); • return false; • } • Return true; • } 6.编译运行
4.1.4 控件的创建与使用 步骤如下: • 将控件添加到对话框模板中 • 在对话框类中增加与控件相关联的数据成员 • 根据需要在对话框类中定义处理这些数据的成员变量 • 在对话框的OnInitDialog函数体中,为控件设置一些初始条件 • 在对话框的控件消息处理函数中,添加控件处理代码
3. 控件的消息WM_COMMAND • MSG结构 • typedef struct tagMSG{ • HWND hwnd; //接收到消息的窗口句柄 • UINT message; .//消息 • WPARAM wParam; // 消息的附加信息,其含义取决于message • LPARAM lParam; //消息的附加信息,其含义取决于message • DWORD time; //消息发送时的时间 • POINT pt; //消息发送时,光标的屏幕坐标 • }MSG;
4.1.5 访问控件 • 关联变量------ClassWizard添加 控件变量——控件类对象,一个窗口对象 m_MyBtn.SetWindowText(“这是一个命令按钮”); 值变量——普通类型CString、int… • DDX对话数据交换与DDV对话数据验证 UpdateData(TRUE); //对于值变量,控件中的值传递变量 UpdateData(FALSE); • 控件窗口指针 CEdit *pEdFirst=(CEdit *) GetDlgItem(ID_FIRSTNAME); 例如 DDX_Text(pDX, IDC_PASSWORD_EDIT, m_password)
访问控件的两种方法 • 采用控件关联变量 值变量 m_iA=10; UpdateData(false); 控件变量 m_EditA.SetWindowText(“10”); • 获取控件窗口指针 CEdit* pEditName=GetDlgItem(IDC_NAME); pEditName->SetWindowText(“ZHANG”); SetDlgItemText(IDC_NAME, m_Name); GetDlgItemText(IDC_NAME, m_Name);
4.2 CStatic类控件 静态控件概述 静态控件属性
1. CStatic类控件的概述 • Static Text:静态文本——作为标签 • Group Box:分组框——框架 • Pictrue:静态图片——显示位图、图标或分割其他控件 • 默认ID为IDC_STATIC • 只有CStatic类控件的ID号可以重复
为对话框添加背景图片 为对话框设置一幅背景图(Bitmap)有几种最常用的方法: • 使用Picture控件:方法简单,一定保证TabOrder为1 • 映射WM_CTLCOLOR消息,在OnCtlColor函数中返回一个图形刷子: • 映射WM_PAINT消息,在OnPaint函数中选入位图
Picture控件 WM_PAINT WM_CTLCOLOR
CBitmapBKDlg::CBitmapBKDlg(CWnd* pParent /*=NULL*/): CDialog(CBitmapBKDlg::IDD, pParent) { …….. CBitmap* pBitmap = new CBitmap; // ASSERT(pBitmap); pBitmap->LoadBitmap(IDB_BACKGROUD); m_BKBrush.CreatePatternBrush(pBitmap); delete pBitmap; } 利用对话框的OnCtlColor() CTLCOLOR_BTN CTLCOLOR_DLG CTLCOLOR_EDIT CTLCOLOR_LISTBOX CTLCOLOR_MSGBOX CTLCOLOR_SCRLLBAR CTLCOLOR_STATIC Private: CBrush m_BKBrush HBRUSH CBitmapBKDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { if (nCtlColor == CTLCOLOR_DLG ) return (HBRUSH)m_BKBrush.GetSafeHandle(); return CDialog::OnCtlColor(pDC,pWnd,nCtlColor); }
利用对话框的OnPaint() void CxxxDlg::OnPaint() { CPaintDC dc(this); // device context for painting CRect rc; GetClientRect(&rc); //获取客户窗口区域 CBitmap *BackBitmap=new CBitmap; //背景位图 BackBitmap->LoadBitmap(IDB_BITMAP1); CDC * m_dc=new CDC; //内存设备环境 m_dc->CreateCompatibleDC(&dc); //兼容 m_dc->SelectObject(BackBitmap); //位图选入环境 dc.BitBlt(0,0,rc.right,rc.bottom,m_dc,0,0,SRCCOPY); delete m_dc; //释放 delete BackBitmap; //释放 }
CDC绘图操作 • CDC::BitBlt从源设备环境拷贝一幅位图到当前设备环境 • BOOL BitBlt ( int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, DWORD dwRop ); • CDC::StretchBlt从源设备环境(矩形)拷贝一幅位图到当前设备环境(矩形),如果必要,延伸或压缩 • BOOLStretchBlt(intx,inty,intnWidth,intnHeight,CDC*pSrcDC,intxSrc,intySrc,intnSrcWidth,intnSrcHeight,DWORDdwRop);
4.3 编辑框 • 概述 • 属性和风格 • 基本操作 • 编辑控件的通知消息
CEdit类控件的操作 • 口令设置 • 用来输入和编辑文本 • 单行文本 • 多行文本 Multiline
CEdit类控件的属性 • Multiline • Number • Want return • Password • Read-only • Uppercase • Lowercase
CEdit类控件的方法 • 口令设置: SetPasswordChar(#); • 选择文本 • 输入/输出文本 -----DDX技术,为编辑框添加值变量,通过使用UpdateData()完成控件与变量之间的数据传送。 ------定义CEdit类的对象或对象指针(P168) CWnd::SetWindowText(); CWnd:: GetWindowText();
CanUndo() Clear() Copy() Cut() EmptyUndoBuffer() GetFirstVisibleLine() GetModify() GetPasswordChar() GetRect() GetSel() LimitText() LineFromChar() LineLength() LineScroll() Paste() ReplaceSel() SetModify() SetPasswordChar() SetReadOnly() SetSel() Undo() CEdit类控件的方法
CEdit类控件的消息 • EN_CHANGE • EN_ERRSPACE • EN_HSCROLL • EN_KILLFOCUS • EN_MAXTEXT • EN_SETFOCUS • EN_UPDATE • EN_VSCROLL
4.4 按钮类(CButton)控件 • 按钮类控件概述 • 按钮类的消息 • 示例
CButton类控件的概述 • 命令按钮(Pushbuttons) • 单选按钮(Radiobuttons) • 复选按钮(Checkboxes)
命令按钮 • 事件: • BN_CLICKED • 方法: • SetWindowText(字符串) • ShowWindow(SW_SHOW/ SW_HIDE); • EnableWindow(false/true);
例4.2一元二次方程求解 void CEx4_2Dlg::OnButton1() { // TODO: Add your control notification handler code here UpdateData(); //将控件显示的数据传递给成员变量 int disc; double realpart,imagepart; //实部、虚部 disc=m_b*m_b-4*m_a*m_c; realpart=(double)-m_b/(2*m_a); imagepart=( double)sqrt(abs(disc))/ (2*m_a); if (disc>=0) //如果disc大于等于0 { m_x1.Format("x1=%6.2f ", realpart + imagepart); m_x2.Format("x2=%6.2f ", realpart - imagepart); } else //如果disc小于0 { m_x1.Format("x1=%6.2f+%6.2fi",realpart,imagepart); m_x2.Format("x2=%6.2f-%6.2fi",realpart,imagepart); } UpdateData(FALSE); // 将成员变量数据传递给控件,并显示 }
单选按钮 • 属性: • Group:与Tab order 管理一组控件 • 事件 • BN_CLICKED • 检查是否选中的方法 (1)IsDlgButtonChecked(ID) (2)连接变量的值:0,1,2,3... .. 注意事项
复选框 • 属性 • 事件 • 检查是否选中的方法 (1)IsDlgButtonChecked(ID) (2)连接变量的值: true/false
开发MyCalculator程序 用VC++6.0编写MFC应用程序,一般有三个步骤: • 创建工程:使用MFC AppWizard创建应用程序的基本框架; • 可视化设计:制做Windows风格的图形用户界面和各种控件; • 编写程序代码。
一、创建工程 • “File/New/Projects/MFC AppWizard[exe]/工程名:MyCalculator,位置:E:\MyVC\ch6” • “选择Dialog based/Next,标题:计算器“,其它接受默认设置; • ”Finish”完成
二、可视化设计 • “Project Workspace”窗口,选择“Resource View”标签,双击Dialog下的“IDD_MYCALCULATOR_DIALOG” • 从“IDD_MYCALCULATOR_DIALOG”对话框删除“OK” 和“ Cancel”及“TODO文本” 。 • 弹出控件工具箱(右击工具栏,选择Controls); • 向对话框添加按钮(Button)控件; • 右击Button1,选择属性
1.可视化设计 • 类似方法按右表定义,编辑对话框资源。设计结果如下图:
2.为编辑框“IDC_DISPLAY”引入变量 • “View/ClassWizard/Member Variable” Class name:CMyCalculatorDlg Ctrol IDS:IDC_DISPLAY Category:Value • 单击Add variable…进行 如下设置
3.为CMyCalculatorDlg类添加数据成员 • 添加变量 在“CMyCalculatorDlg.h”中,为CMyCalculatorDlg类加入四个变量(protected): • double m_first;//存储一次运算的第一个操作数及一次运算的结果 • double m_second;//存储一次运算的第二个操作数 • CString m_operator;//存储运算符 • double m_coff;//存储小数点的系数权值
CMyCalculatorDlg::CMyCalculatorDlg(CWnd* pParent /*=NULL*/): CDialog(CMyCalculatorDlg::IDD, pParent) { //{{AFX_DATA_INIT(CMyCalculatorDlg) m_display = _T("0.0"); m_first = 0.0; m_second= 0.0; m_operator=_T("+"); m_coff = 1.0; //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } • 在构造函数中初始化成员变量 • 注此函数在“CMyCalculatorDlg.cpp”中
4.为Button按钮的BN_CLICKED事件添加响应函数 • 用向导添加 “View/ClassWizard/Message Maps” Class name:CMyCaculatorDlg Object IDS:IDC_BUTTON0 Message:BN_CLICKED 单击”Add Function” • 直接在MyCalculatorDlg.cpp中添加,如下 BEGIN_MESSAGE_MAP(CMyCalculatorDlg, CDialog) //{{AFX_MSG_MAP(CMyCalculatorDlg) …… ON_BN_CLICKED(IDC_BUTTON0, OnButton0) …… //}}AFX_MSG_MAP END_MESSAGE_MAP()
三、编写程序代码 添加响应函数后,在MyCalculatorDlg.cpp文件中进行了函数的定义,函数体为空,可用以下几种方法填写代码。 • 在”MFC ClassWizard”对话框的”Message Maps”标签页,选中消息响应函数,单击“Edit Code” • 在工作区的”ClassView”下,CMyCalculatorDlg类中双击相应的响应函数。 • 直接在MyCalculatorDlg.cpp文件中填写对应函数的函数体。 • 程序代码见演示
编写程序代码 • 数字”N”的消息响应函数(N=0,1,…9) void CMyCalculatorDlg::OnButtonN() { if( m_coff == 1.0) m_second = m_second*10 + N;//作为整数输入数字时 else { m_second = m_second + N*m_coff; //作为小数输入数字 m_coff *= 0.1; } UpdateDisplay(m_second);//更新编辑框的数字显示 }
编写程序代码 • 如数字”8”的消息响应函数 void CMyCalculatorDlg::OnButton8() { if(m_coff=1.0) m_second=m_second*10+8;else { m_second=m_second+m_coff*8; m_coff*=0.1; }UpdateDisplay(m_second);} 输入123.123 1*10+2=12 12*10+3=123 . 0.1 1 123+0.1*1=123.1 123.1+0.01*2=123.12 123.12*0.001*3=123.123
运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。 算法如下: m_first与m_second 作m_operator运算后→m_first; 0 →m_second; m_first→m_display 当前点击的运算符→m_operator; 将小数的权值变量m_coff置1.0. 详见演示
void CMyCalculatorDlg::OnButtonAdd() { Calculate(); m_operator="+"; } • 如”+”运算符 注:Calculate(); 类的成员函数 右击”CMyCalculatorDlg”类,选择”Add Member Function” void CMyCalculator::Calculate() { switch(m_operator.GetAt(0)) { case '+':m_first+=m_second;break; case '-':m_first-=m_second;break; case '*':m_first*=m_second;break;