第
Download
1 / 96

第 六 章 对话框与控件 - PowerPoint PPT Presentation


  • 103 Views
  • Uploaded on

第 六 章 对话框与控件. VC++ 系统开发. 河北经贸大学 信息技术学院. 本章导读. 本章通过开发一个计算器和口令对话框程序,掌握 Button 、 Edit Box 和 Static Text 控件的使用方法 其他常用控件的使用技巧 , 如 List Control 基于对话框的应用程序的编程技术 模式对话框、非模式对话框和通用对话框的设计与调用。. 本章主要内容. 通用对话框 常用控件介绍 MyCalculator 程序 开发 MyCalculator 程序 口令对话框. 6.1 对话框概述. 对话框 对话框编辑器 对话框编程

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about ' 第 六 章 对话框与控件' - zanna


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

六章对话框与控件

VC++系统开发

河北经贸大学

信息技术学院


本章导读

  • 本章通过开发一个计算器和口令对话框程序,掌握Button、Edit Box和Static Text控件的使用方法

  • 其他常用控件的使用技巧,如List Control

  • 基于对话框的应用程序的编程技术

  • 模式对话框、非模式对话框和通用对话框的设计与调用。


本章主要内容

通用对话框

常用控件介绍

MyCalculator程序

开发MyCalculator程序

口令对话框


6.1 对话框概述

  • 对话框

  • 对话框编辑器

  • 对话框编程

  • 控件的创建与使用


6 1 1 p154
6.1.1 对话框 P154

  • 可视化的界面,包含:按钮、文本框、复选框等。

  • 对话框是一个窗口,控件也是一个窗口

  • 对话框的两种消息:

    WM_INITDIALOG:数据成员的初始化

    WM_COMMAND:控件的消息

  • MFC对对话框的支持:对话框从CDialog基类中派生一个类, MFC的CDialog类封装了用于对话框的显示、关闭等常用操作的许多功能函数;MFC程序框架;ClassWizard类向导

  • 公共对话框: P154表6-1

  • 对话框控件及其CWnd成员函数 表6-2/表6-3

  • 模式对话框和无模式对话框


对话框的类型P156

  • 1.模式对话框

    弹出后,用户必须作出相应得操作,否则不可以继续。 用途广。

  • 2.无模式对话框

    弹出后,一直保留在屏幕上,其他操作可继续,用的时候激活对话框即可。

    两者的终止函数不一样:

    Cdialog::EndDialog------模式

    CWnd::DestroyWindow-----无模式

    所占内存空间不同:

    模式对话框: 由系统自动分配内存,当对话框退出时,对话框对象自动删除。

    无模式对话框: 则需要用户来指定内存,退出时用户删除对话框对象


6 1 2
6.1.2 使用对话框编辑器

  • 添加、选取、删除对话框控件;

  • 改变控件的Tab键次序;

  • 利用基准线、标尺及布局工具进行控件的布局;

  • 测试所编辑的对话框的性能。


P160 164
对话框编程步骤p160-164

  • 添加对话框资源

    在单文档项目MyHello中,Insert-〉resourc(ctrl+R)-〉Dialog

  • 编辑对话框属性

  • 向对话框内添加控件

    ——添加/选取/控件的布局/测试对话框

  • 使用ClassWizard,为对话框资源创建一个新类CMyDlg,为控件进行消息映射

    afx_msg void OnButton1(); //向导完成

    ON_BN_CLICKED(IDC_BUTTON1, OnButton1) //向导完成

  • 在OnButton1()中添加用户代码

    MessageBox("欢迎进入对话框的设计!");

  • 在程序(MyHello.cpp)中使用模式对话框

    #include “MyDlg.h”

    CMyDlg Dlg; // MyHelloApp::InitInstance()

    Dlg.DoModal();


6 1 4 p164 168
6.1.4 控件的创建与使用p164-168

步骤如下:

  • 将控件添加到对话框模板中

  • 在对话框类中增加与控件相关联的数据成员

  • 根据需要在对话框类中定义处理这些数据的成员变量

  • 在对话框的OnInitDialog函数体中,为控件设置一些初始条件 m_MyBtn.SetWindowText("欢迎");

  • 在对话框的控件消息处理函数中,添加控件处理代码


访问控件 P168

  • 关联变量------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)


综合示例一 ----模式对话框与无模式对话框的编程(口令对话框)

  • 为MyHello程序添加”口令”对话框


预备知识

1.对话框类型

  • 对话框是实现人机交互的重要手段,对话框不但可以接收消息,而且可以被移动和关闭.

  • 无模式对话框

  • 模式对话框

允许用户在该对话框与应用程序其他窗口之间的切换

不允许用户在关闭对话框之前切换到应用程序的其他窗口


对话框设计方法

  • 创建对话框资源,并添加各种所需控件;

  • 创建对话框类(CDialog)的派生类,并将其与已创建的对话框资源相连接;

  • 在派生类中添加所需的数据成员变量、数据交换函数(DDX)和数据验证函数(DDV) ;

  • 为对话框各控件添加消息响应函数,编写程序代码;

  • 为对话框的调用者添加对话框的调用。


数据交换和验证 2

运行对话框,修改文档对象

4

创建对话框模板 1

定义对话框类和公有成员变量  3

Public:

数据成员

文档对象

xxxxxxx

xxxxxxx

xxxxxxx

xxxxxxx

对话框设计方法

对话框的工作原理

休息


对话框的调用

  • 调用模式对话框

    • CPasswordDialog m_Dlg;//声明对话框对象

    • m_Dlg.DoModal();//显示模态对话框

    • 用户必须单击”确定(OK)“或”取消(Cancel)”才能切换到其它窗口或对话框。


  • 调用非模式对话框

    • 在视图类的头文件中添加CPasswordDialog的指针变量:CPasswordDialog *m_Dlg; //指针

    • 在视图类的构造函数中将其初始化m_Dlg=NULL;

    • 在调用函数中添加如下代码if(m_Dlg==NULL){m_Dlg=new CPasswordDialog;// 动态创建m_Dlg->Create(IDD_PASSWORD_DIALOG,this);}m_Dlg->ShowWindow(SW_SHOW);//显示非模态对话框

对话框的调用


  • 编辑对话框资源

    • Button ID: IDOK ; Caption: 确认

    • Button ID: IDCANCEL ; Caption: 取消

    • Static Text: ID : IDC_STATIC Caption: 请输入口令:


创建“口令”对话框类-----类向导

  • 创建对话框类

    右键单击对话框→Class Wizard →Adding Class对话框

    →Create a new className:CPasswordDialogBase class:CDialogDialogID: IDD_PASSWORD_DIALOG

  • 创建了一个类(CPasswordDialog),两个文件(PasswordDialog.h和PasswordDialog.cpp)


为编辑框引入变量

  • “Member Variable”标签页Class name:CPasswordDialogControl IDs:IDC_PASSWORD_EDIT

  • 单击”Add Variable……”,显示Add Member Variable对话框

    • Variable name:m_Password

    • Category: Value

    • Variable type:CString

创建: DDX_Text(pDX, IDC_PASSWORD_EDIT, m_password)


调用“口令”对话框

修改应用程序类的InitInstance()函数

BOOL CMyHelloApp::InitInstance()

{ ……

CPasswordDialog Dlg; //声明CPasswordDialog类的对象

if(Dlg.DoModal() != IDOK) return false;//用户按下的不是"确认"按钮

if(Dlg.m_Password != "123456")

//口令设为字符串"123456"

{AfxMessageBox("口令错误,确认后将退出程序");

return false;

}

return TRUE;

}

模式对话框的调用

在MyHello.cpp头部加入包含语句#include”PasswordDialog.h”


显示非模式对话框

  • 例如,在MyHello程序中,添加一菜单项,当点击该菜单项时,将口令对话框以非模式显示:

  • 编辑菜单ID:ID_MODALLESSCaption:非模式对话框


  • CPasswordDialog *m_pModallessDlg;

  • 需要在MyHelloView.h中加入:

  • #include "PasswordDialog.h"

  • 修改视图类的构造函数和析构函数

  • 构造函数:m_pModallessDlg=NULL;

  • //初始化指针

  • 析构函数:if(m_pModallessDlg!=NULL)

  • delete m_pModallessDlg;//释放空间

或者:

if(m_pModallessDlg!=NULL){

m_pModallessDlg->DestroyWindow();

m_pModallessDlg=NULL;


  • “View/ClassWizard/MFC ClassWizard”

  • Object IDS:ID_NOMODALLESS

  • Class name:CMyHelloView

  • Messages:COMMAND

  • 添加了消息响应函数”OnModalless()”,单击”Edit Code”

  • 编写代码如下:

  • if(m_pModallessDlg==NULL)

  • {m_pModallessDlg=new CPasswordDialog;// 动态创建

  • m_pModallessDlg->Create(IDD_DIALOG1,this);}

  • m_pModallessDlg->ShowWindow(SW_SHOW);//显示非模态对话框


技术要点总结:

  • 对话框控件和相关MFC类(P155,表6-2)

  • 用于对话框控件的CWnd成员函数(P155,表6-3)

  • 对话框编辑器

  • 控件工具箱:”右击工具栏/control”“Tools/Customize…/ToolsBars/Control”

  • 修改控件的Tab键次序:”编排(Layout)/Tab Order”;或Ctrl+D按新的次序依此用鼠标单击各个控件,新的Tab键次序即可生成.

  • 控件布局工具栏:P159,图6-5,设置Layout/Guide Setings

  • 测试对话框:Ctrl+T


技术要点

对话框左上角在父窗口中的坐标(居中)

  • 为控件设置初始条件(P165(4))在对话框的OnInitDialog函数体中,为控件设置初始条件

  • 按钮控件的属性说明(P167)

  • 消息对话框(P204)


6 2 windows

6.2 windows 标准控件

CStatic类控件的使用

CEdit类控件的使用

CButton类控件的使用

CListBox类控件的使用

CComBox类控件的使用


Windows
windows 标准控件

  • 属性

  • 方法

  • 事件

  • 对话框类的成员变量-控件关联变量

    • value

    • Control


访问控件的两种方法

  • 采用控件关联变量

    值变量 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);


1 cstatic
1. CStatic类控件的使用

  • Static Text:静态文本——作为标签

  • Group Box:分组框——框架

  • Pictrue:静态图片——显示位图或分割其他控件

    • 默认ID为IDC_STATIC

    • 只有CStatic类控件的ID号可以重复

      详见P169


为对话框添加背景图片

为对话框设置一幅背景图(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);

}


利用对话框的 CDialog(CBitmapBKDlg::IDD, pParent)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 CDialog(CBitmapBKDlg::IDD, pParent)绘图操作

  • 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);


2 cedit
2. CEdit CDialog(CBitmapBKDlg::IDD, pParent)类控件的使用

  • 用来输入和编辑文本

  • 单行文本

  • 多行文本  Multiline

  • 口令

    详见P170


Cedit
CEdit CDialog(CBitmapBKDlg::IDD, pParent)类控件的属性

  • Multiline

  • Number

  • Want return

  • Password

  • Read-only

  • Uppercase

  • Lowercase


Cedit1
CEdit CDialog(CBitmapBKDlg::IDD, pParent)类控件的方法

  • 口令设置:

    SetPasswordChar(#);

  • 选择文本

  • 输入/输出文本

    -----DDX技术,为编辑框添加值变量,通过使用UpdateData()完成控件与变量之间的数据传送。

    ------定义CEdit类的对象或对象指针(P168)

    CWnd::SetWindowText();

    CWnd:: GetWindowText();


Cedit2

CanUndo() CDialog(CBitmapBKDlg::IDD, pParent)

Clear()

Copy()

Cut()

EmptyUndoBuffer()

GetFirstVisibleLine()

GetModify()

GetPasswordChar()

GetRect()

GetSel()

LimitText()

LineFromChar()

LineLength()

LineScroll()

Paste()

ReplaceSel()

SetModify()

SetPasswordChar()

SetReadOnly()

SetSel()

Undo()

CEdit类控件的方法


Cedit p171 6 11
CEdit CDialog(CBitmapBKDlg::IDD, pParent)类控件的事件 (P171表6-11)

  • EN_CHANGE

  • EN_ERRSPACE

  • EN_HSCROLL

  • EN_KILLFOCUS

  • EN_MAXTEXT

  • EN_SETFOCUS

  • EN_UPDATE

  • EN_VSCROLL


3 cbutton p171
3. CButton CDialog(CBitmapBKDlg::IDD, pParent)类控件的使用(P171)

  • 命令按钮(Pushbuttons)

  • 单选按钮(Radiobuttons)

  • 复选按钮(Checkboxes)


命令按钮 CDialog(CBitmapBKDlg::IDD, pParent)

  • 事件:

  • BN_CLICKED

  • 方法:

  • SetWindowText(字符串)

  • ShowWindow(SW_SHOW/ SW_HIDE);

  • EnableWindow(false/true);

    例6-1 p172


一元二次方程求解 CDialog(CBitmapBKDlg::IDD, pParent)

void CEx6_2Dlg::OnButton1()

{

// TODO: Add your control notification handler code here

UpdateData();

int disc;

double re,im;

disc=m_B*m_B-4*m_A*m_C;

re=(double)-m_B/(2*m_A);

im=(double)sqrt(abs(disc))/(2*m_A);

if(disc>=0)

{

m_X1.Format("X1=%6.2f",re+im);

m_X2.Format("X2=%6.2f",re-im);

}

else

{

m_X1.Format("X1=%6.2f+%6.2f i",

re,im); m_X2.Format("X2=%6.2f-%6.2f i",

re,im);

}

UpdateData(FALSE);

}


单选按钮 CDialog(CBitmapBKDlg::IDD, pParent)

  • 属性:

    • Group:与Tab order 管理一组控件

  • 事件

    • BN_CLICKED

  • 检查是否选中的方法

    (1)IsDlgButtonChecked(ID)

    (2)连接变量的值:0,1,2,3... ..

    注意事项:P172(1)(2)(3)


复选框 CDialog(CBitmapBKDlg::IDD, pParent)

  • 属性

  • 事件

  • 检查是否选中的方法

    (1)IsDlgButtonChecked(ID)

    (2)连接变量的值: true/false

  • 例6-2(P174)


综合示例二 CDialog(CBitmapBKDlg::IDD, pParent)-----一个简单的整数计算器

  • 一个简单的整数运算计算器(演示)


编辑框与按钮类控件作业 CDialog(CBitmapBKDlg::IDD, pParent) 一个功能较丰富的计算器程序设计

演示

休息


Mycalculator
开发 CDialog(CBitmapBKDlg::IDD, pParent)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.可视化设计 CDialog(CBitmapBKDlg::IDD, pParent)

  • 类似方法按右表定义,编辑对话框资源。设计结果如下图:


2 idc display
2.为编辑框“ CDialog(CBitmapBKDlg::IDD, pParent)IDC_DISPLAY”引入变量

  • “View/ClassWizard/Member Variable”

    Class name:CMyCalculatorDlg

    Ctrol IDS:IDC_DISPLAY

    Category:Value

  • 单击Add variable…进行

    如下设置


3 cmycalculatordlg
3.为 CDialog(CBitmapBKDlg::IDD, pParent)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
4.为 CDialog(CMyCalculatorDlg::IDD, pParent)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()


三、编写程序代码 CDialog(CMyCalculatorDlg::IDD, pParent)

添加响应函数后,在MyCalculatorDlg.cpp文件中进行了函数的定义,函数体为空,可用以下几种方法填写代码。

  • 在”MFC ClassWizard”对话框的”Message Maps”标签页,选中消息响应函数,单击“Edit Code”

  • 在工作区的”ClassView”下,CMyCalculatorDlg类中双击相应的响应函数。

  • 直接在MyCalculatorDlg.cpp文件中填写对应函数的函数体。

  • 程序代码见演示


编写程序代码 CDialog(CMyCalculatorDlg::IDD, pParent)

  • 数字”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);//更新编辑框的数字显示

    }


编写程序代码 CDialog(CMyCalculatorDlg::IDD, pParent)

  • 如数字”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;


需要在运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。MyCalculatorDlg.cpp中添加math.h文件

case '/':

if(fabs(m_second)<=0.000001)

{m_display="除数不能为0";

UpdateData(false);

return;

}

m_first/=m_second;break;

}

m_second=0.0;

m_coff=1.0;

UpdateDisplay(m_first);//更新编辑框显示内容

}

  • 如”+”运算符


void CMyCalculatorDlg::UpdateDisplay(double lVal)运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。

{ m_display.Format(_T("%f"),lVal);

int i=m_display.GetLength();

//格式化输出,将输出结果后的零截去

while(m_display.GetAt(i-1)=='0')

{ m_display.Delete(i-1,1);i--; }

UpdateData(false);//更新编辑框变量m_display

}

  • UpdateDisplay()添加方法同上


算法如下:运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。

m_first与m_second 作m_operator运算后→m_first;

m_first→m_display (显示)

0 →m_second;

0 →m_second;

0 →m_first;

将小数的权值变量m_coff置1.0.

输入的运算符→ m_operator

详见演示

  • 为”=“按钮的消息响应函数添加代码:

  • 为其它按钮的消息响应函数添加代码:见演示


为“。”按钮添加消息处理函数运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。

void CMyCalculatorDlg::OnButtonReciprocal() //1/x按钮的消息处理函数

{

if(fabs(m_second)<0.000001)

{m_display = "除数不能为零";

UpdateData(false);

return; }

m_second= 1.0/m_second;

UpdateDisplay(m_second);

}

void CMyCalculatorDlg::OnButtonPoint()

{

m_coff = 0.1 ;

}


技术要点运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。

  • 关于UpdateData函数:

    CDialog的基类CWnd的成员函数,函数原型

    BOOL UpdateData(BOOL bSaveAndValidate=TRUE);

    一般在对话框的派生类中,利用UpdateData()进行控件和相应变量之间的数据传递

    UpdateData(TRUE);// 将控件中的数据传递给相应的变量

    UpdateData(FALSE);// 将变量中的数据传递给相应的控件


技术要点运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。

  • 关于消息响应函数:

    用MFC ClassWizard为对话框中某按钮的BN_CLICKED事件添加消息处理函数时, MFC ClassWizard作了三件事:

    (1)在类的定义MyCalculatorDlg.h中添加了消息响应函数的函数原型;

    (2)在类的实现文件MyCalculatorDlg.cpp中,添加了函数体;

    (3)在类的实现文件MyCalculatorDlg.cpp中,添加了消息映射。


技术要点运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。

  • 数据交换和校验:

    对话框数据交换(DDX)可以实现对话框中控件数值的初始化和获取用户的数据输入。

    对话框数据校验(DDV)可以实现对对话框中数值进行校验 。如为IDC_DISPLAY的Edit Box控件创建了m_display变量,数据类型为CString,则ClassWizard自动在文件MyCalculatorDlg.cpp中创建了相应的对话框数据交换代码:


技术要点运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。

void CMyCalculatorDlg::DoDataExchange(CDataExchange* pDX)

{ CDialog::DoDataExchange(pDX);

//{{AFX_DATA_MAP(CMyCalculatorDlg)

DDX_Text(pDX, IDC_DISPLAY, m_display);

//}}AFX_DATA_MAP

}

  • 数据交换和校验:

在代码中,利用CWnd::UpdateData()进行控件和相应变量之间的数据传递

UpdateData(TRUE);// 将控件中的数据传递给相应的变量

UpdateData(FALSE);// 将变量中的数据传递给相应的控件


技术要点运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。

  • 构造函数:

    CString();//产生一个空的CString对象

    CString(const CString&stringSrc);//用另一个CString对象的值初始化对象.

    CString(TCHAR ch,int nRepeat=1);//重复字符

    CString(LPCTSTR lpch,int nLength);//字符数组指定长度

    CString(const unsigned char *psz);//无符号字符指针

    CString(LPCWSTR lpsz);//Unicode字符串

    CString(LPCSTR lpsz);//ANSI字符串

  • 字符串CString类:

    CString类中的字符是TCHAR类型的。


技术要点运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。

  • 常用成员函数:

    int GetLength() const;//测试长度

    BOOL IsEmpty() const;//测试为空

    void Empty();//置空

    TCHAR GetAt(int nIndex) const;获取指定位置处字符

    void SetAt(int nIndex,TCHAR ch); 设定字符

    MakeUpper(); 变为大写

    MakeLower(); 变为小写

    int Compare(LPCTSTR lpsz) const;字符串比较

    int CompareNoCase(LPCTSTR lpsz) const;字符串比较,忽略大小写


技术要点运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。

  • 例1

    CString m_str1=“下午”,m_str2=“好!”;

    CString m_str3=m_str1+m_str2;

  • 例2

    CString m_str1=“a”,m_str2=“b!”;

    int result=m_str1.Compare(m_str2);字符串比较

    if(result==0) AfxMessageBox(“两者相同”);

    else if (result>0) AfxMessageBox(“m_str1>m_str2”);

    else AfxMessageBox(“m_str1<m_str2”);


Mycalculator1
优化运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。MyCalculator程序

  • 利用ON_COMMAND_RANGE宏,可以处理一系列控件对同一消息处理函数的响应,用以下方法修改程序:

(1) 在MyCalculatorDlg.h中“{{AFX_MSG(C MyCalculatorDlg)”与”}}AFX_MSG”之间添加下面语句:

afx_msg void OnOperandInput(UINT nID);

(2)在MyCalculatorDlg.cpp中“{{AFX_MSG_MAP(C MyCalculatorDlg)”与”}}AFX_MSG_MAP” 间添加下面语句

ON_COMMAND_RANGE(IDC_BUTTON0,IDCBUTTON9,OnOperandInput);

(3)在Resource.h文件中定义

#define IDC_BUTTON0 1000

……

#define IDC_BUTTON9 1009

起始值

结束值

消息响应函数


Mycalculator2
优化运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。MyCalculator程序

void CCalculatorDlg::OnOperandInput(UINT nID)

{int n=nID%10;

if(m_coff=1.0)

m_second=m_second*10+n;

else

{ m_second=m_second+m_coff*n;

m_coff*=0.1;

}

UpdateDisplay(m_second);

}


操作练习运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。

  • 完成计算器的设计

  • 优化MyCalculator程序


4 clistbox clistctrl
4. 运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。列表类控件CListBox /CListCtrl

  • CListBox控件 单选/多选列表框P177-180

    只能显示一个字段

  • CListCtrl控件: 类似于资源管理器的显示

    可以显示一条记录


Clistbox
CListBox 运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。类控件属性

列表框控件提供一个项目列表,用户可以从中选择一个或多个项目。见P178表6-18

  • Sort:列表框项目排序

  • multi-column:有水平滚动条的多列列表框

  • Horizontal scroll:创建水平滚动条

  • vertical scroll

  • want key input:向父窗口发送消息

  • disable no scroll


Clistbox1
CListBox运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。控件的常用操作

添加列表项

  • AddString()

  • InsertString()

  • DeleteString()

  • ResetContent()

  • FindString()

  • FindStringExact()

  • SelectString()

删除列表项

查找列表项


列表框的单项选择函数(运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。P179)

  • GetCurSel()返回列表框中当前选择字符串的基于0的索引

  • SetCurSel()设定选中列表项字符串


列表框多项选择函数运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。

  • GetSelCount()返回多选列表框中当前选择的字符串的数目

  • GetSetItems() :

  • SetSel()


Clistbox p180 6 19
CListBox 运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。类控件事件 P180表6-19

  • LBN_DBLCLK

  • LBN_ERRSPACE

  • LBN_KILLFOCUS

  • LBN_SELCANCEL

  • LBN_SELCHANGE

  • LBN_SETFOCUS


单选列表框获取数据运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。

int nSelection=m_ListBox.GetCurSel()

m_ListBox.GetText(nSelection,m_Text);

其中:

int 型获得选择项序号

CString型 获得选择项文本项

例6-3(P180)单选列表框的使用


多选列表框获取数据运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。

  • int nSelection=m_ListBox.GetSelCount();

  • int items[20]; //索引号数组

  • String str[20]; //字符串数组

  • m_ListBox.GetSelItems(items);

  • for(int i=0;i<nSelection;i++)

  • {m_ListBox.GetText(items[i],str[i]);


Clistctrl
CListCtrl运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。控件的用法

  • Windows资源管理器中的“查看”标签下的“大图标、小图标、列表、详细资源”就是一个列表控件的典型应用。显示记录

  • 列表控件的风格

  • 列表控件的2个数据结构

  • 列表控件的常用操作

  • 列表控件的消息

  • 列表控件的具体编程


Clistctrl1
CListCtrl运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。示例

CListCtrl详解


5 ccombox p183 185
5. CComBox 运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。控件 P183-185

  • 编辑框+列表框用户可以通过在组合框中输入文本来选定项目,也可以直接从列表框中选定项目。如果项目数超过了组合框中可显示的数目控件上自动添加滚动条。见P183

  • 类型:

    • Simple:简单组合框,列表框直接显示出来

    • Dropdown:下拉式组合框,点击下拉按钮

    • Drop List:下拉式列表框,无文字编辑功能


Ccombox
CComBox 运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。类控件事件

  • CBN_DBLCLK

  • CBN_ERRSPACE

  • CBN_KILLFOCUS

  • CBN_SELECTCANCEL

  • CBN_SELECTCHANGE

  • CBN_SETFOCUS

  • CBN_CLOSEUP

  • CBN_DROPDOWN

  • CBN_EDITCHANGE

  • CBN_EDITUPDATE

  • 例6-4(P185)


6 cscrollbar cslider cspin
6. 运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。滚动类控件CScrollBar/CSlider/CSpin

滚动条的事件

  • SB_BOTTOM / SB_RIGHT

  • SB_TOP / SB_LEFT

  • SB_LINEDOWN/ SB_LINERIGHT

    • 单击滚动条向下箭头时

  • SB_LINEUP / SB_LINELEFT

  • SB_PAGEDOWN/SB_PAGERIGHT

    • 单击向下箭头与滚动块之间区域

  • SB_PAGEUP / SB_PAGELEFT

  • SB_THUMBPOSITION

  • SB_THUMBTRACK//拖动滚动滑块时

  • SB_ENDSCROLL


Cscrollbar
CScrollBar运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。控件的方法

  • EnableScrollBar()

  • GetScrollInfo()

  • GetScrollLimit()

  • GetScrollPos()

  • GetScrollRange()

  • SetScrollInfo()

  • SetScrollPos()

  • SetScrollRange()

  • ShowScrollBar()


滚动条初始化运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。

BOOL CExam7_4Dlg::OnInitDialog()

{

CDialog::OnInitDialog();

......

m_Scrollbar.SetScrollRange(-20,40);

//设置滚动条的滚动范围-20-40

m_Scrollbar.SetScrollPos(0);

//设置滚动条的当前位置

return TRUE; // return TRUE unless you set the focus to a control

}


滚动条消息映射函数运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。

  • void CExam7_4Dlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)

  • nSBCode:控件消息码

  • nPos:滚动块位置

  • pScrollBar:滚动条对象指针

  • 例6-5(P192) 6-6 (P196)


4 5 200 204
4.5 运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。通用对话框(详见教材200-204)

  • CColorDialog:颜色对话框

  • CFileDialog:打开/保存/新建文件

  • CFindReplaceDialog:查找/替换

  • CFontDialog:字体

  • CPrintDialog:打印

  • CPageSetupDialog:页面设置

    他们都是从一个公共的基类CCommandDialog派生而来,其资源全部包含在\windows\system\commdlg.dll中。

    其共同特点是:从用户处获取信息,但并不对信息做处理。要对信息进行处理需要用户添加代码。

见P154表6-1


文件对话框类运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。

  • Ex6_7(P201)

  • 调用打开文件对话框的关键代码CString strFilter=“Dat Files(*.dat)|*.dat|All Files(*.*)|*.*||”;CFileDialog FileDlg(true, //打开,false保存NULL,NULL, //指定默认扩展名和初始文件名OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, //设置对话框属性(LPCSTR)strFilter, //指定过滤字符串this); //指向父窗口或拥有者窗口的指针


文件对话框类运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。

  • if(FileDlg.Domodal()!=IDOK) return;CString strFileName=FileDlg.GetPathName();//打开文件strFileNameCFile nFile;n file.Open(strFileName,CFile::modeRead,NULL);//以只读方式打开该文件


补充 系统集成(一)运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。


步骤运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。

  • 新建对话框应用程序;

  • 将各个子系统的EXE文件复制到debug/项目文件夹下;

  • 添加命令按纽

  • 添加命令消息处理函数的代码如下:

    ShellExecute(NULL,NULL,"MyCalculator.exe",NULL,NULL,SW_SHOWNORMAL);


系统集成(二)运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。

  • 新建对话框应用程序,布局主界面

  • 插入一个新的对话框资源,添加类CDlg1

  • 插入另一个对话框资源,添加类CDlg2

  • 插入另一个对话框资源,添加类CDlg3

  • 插入另一个对话框资源,添加类CDlg4

  • 编写主界面的按钮消息处理函数,模式对话框的调用

  • CDlg1 dlg1.DoModal();


作业运算符按钮的消息响应函数:将前一次数据与当前数据进行运算,作为下次的第一操作数,并在编辑框显示。

  • 6-1

  • 6-2

  • 6-3

  • 6-4

  • 计算器的设计与实现


ad