资源描述
用VC++做计算器
在这一章,要实现一个简单计算器。其类似于 Windows附件中自带的计算器。实际
效果如图 3-1所示,这个计算器不仅实现了简单的四则运算功能,还实现了高级的科学
计算功能,而且具有简洁大方的图文外观。该计算器具有一个菜单栏,一个编辑框及若
干按键。编辑框可以用任何指定的字体和颜色显示文本。按钮控件具有对鼠标敏感的功
能,当鼠标处于不同的位置和状态时,按钮控件会显示不同的颜色,并且所有按钮控件
的客户区域为椭圆或圆形。
其实际效果如图 3-1所示:
图 3-1计算器示例效果图
●为对话框添加菜单。
●制定高级按钮控件,该按钮具有不规则的形状,并可以根据用户鼠标的位置和点
击状态的不同,显示不同的颜色。
●制定高级编辑控件,该编辑控件可以指定文本文字的字体和颜色。
●实现对话框的扩展功能。
3.1窗体设计
该计算器是基于对话框的应用程序,利用 MFC AppWizard生成应用计算器应用程
序框架,具体步骤如下:
(1)执行 VC程序,选择 FILE|New命令,弹出 New对话框,单击 Projects选项卡,
选择 MFC AppWizard(exe)选项,然后在 Project Name文本框中输入 Calculator。Location
文本框是指项目的本地路径,这里读者可以自行设定。保持 Platform里的 Win32复选框
不变。如图 3-2所示。
(2)单击 OK按钮,弹出 MFC AppWizard-Step1对话框。选择 Dialog Based单选
按钮。如图 3-3所示。
Visual C ++简明教程
图3-2 New对话框
图 3-3 MFC AppWizard-Step1对话框
(3)单击 Next按钮,弹出 MFC AppWizard-Step2 of 6对话框。如图 3-4所示。
(4)单击 Next按钮,弹出 MFC AppWizard-Step3 of 6对话框,如图 3-5所示。
图 3-4 MFC AppWizard-Step2对话框
图 3-5 MFC AppWizard-Step3对话框
(5)单击 Next按钮,弹出 MFC AppWizard-Step4 of 6对话框。如图 3-6所示。
点击 Finish按钮,创建框架。
图 3-6 MFC AppWizard-Step4对话框
3.2编辑资源
因为在利用 MFC AppWizard生成计算器工程时,选择的应用程序类型是对话框应
用程序,所以工程刚建立时,就已经具有如图 3-7所示的对话框资源。
图 3-7初始状态的对话框资源
接下来就在它的基础上,编辑和添加其它的资源。
3.2.1编辑对话框及控件资源
利用 Visual C++提供的资源编辑器对对话框资源进行编辑。删除对话框上默认的
OK和 Cancel按钮。添加一个 Edit控件,其控件 ID为 IDC_DSPEDIT。添加若干按扭控
件,其 ID如表 3-1所示。
表 3-1按扭控件资源清单
按钮名称
按钮 ID
用途
0
BTN_0
BTN_1
BTN_2
BTN_3
BTN_4
BTN_5
BTN_6
BTN_7
BTN_8
BTN_9
按键 0
按键 1
按键 2
按键 3
按键 4
按键 5
按键 6
按键 7
按键 8
按键 9
小数点
求值
1
2
3
4
5
6
7
8
9
.
BTN_10
BTN_11
BTN_12
BTN_13
BTN_14
BTN_15
BTN_16
BTN_17
BTN_18
BTN_19
=
+
加号
-
减号
*
乘号
/
除号
CE
sqrt
1/x
sin
清屏
开方
倒数
正弦
Visual C ++简明教程
cos
tan
x^2
x^3
x^y
exp
ln
BTN_20
BTN_21
BTN_22
BTN_23
BTN_24
BTN_25
BTN_26
BTN_27
作弦
正切
平方
立方
以 x为底的 y次幂
以 e为底的幂
以 e为底的对数
对数
log
并且添加三个静态框,将编辑控件、普通计算、高级计算分别分组。其效果如图 3-8
所示:
图 3-8编辑对话框资源
3.2.2编辑菜单资源
下面为计算器添加一个菜单资源。在 Visual C++中的 Workspace工具条中,选中
ResourceView选项卡。在其中的 Menu项上单击鼠标右键,在弹出的快捷菜单中选择
InsertMenu命令。如图 3-9所示。
图 3-9添加菜单资源
这样就为计算器添加了一个菜单资源,将其 ID更改为 IDR_MENU。利用资源编辑
器对菜单进行编辑。编辑后的菜单如图 3-10所示。
图 3-10编辑菜单资源
3.3实现高级按钮控件类
利用 ClassWizard添加一个新类。如图 3-11所示:
图 3-11添加 CAdvButton类
添加新类名称为 CAdvButton,其父类为 CButton类。我们就在这个类中实现高级的
按钮控件。
3.3.1添加成员变量和成员函数
要实现的高级按钮控件需要对鼠标的移动和点击作出相应的颜色变化。首先在
CAdvButton的头文件里加入几种预定义颜色,其代码如下:
#define DesiableColor RGB(192,192,192)
//灰色,按钮不可用
//红色,按钮拥有焦点
//绿色,按钮被按下
//蓝色,默认
#define FocusColor
#define SelectColor
#define DefaultColor
#define TextColor
RGB(255,0,0)
RGB(0,255,0)
RGB(0,0,255)
RGB(128,128,128)
//浅灰色,文本颜色
如果读者需要将按钮设定为其它颜色,那么只需改动上面的预定义即可。
接下来,添加成员变量:
public:
CRect
CRgn
m_ClientRect;
//用来保存按钮的客户的矩形区域
m_ClientRgn ; //用来保存按钮的客户区域,非矩形
BOOL
m_IsTimerOn;
//标志计时器是否已经打开
Visual C ++简明教程
UINT
m_State;
//按钮所处状态
//当前鼠标位置
CPoint
m_Point;
利用 ClassWizard添加下列消息映射和响应函数:
//消息响应函数
protected:
//{{AFX_MSG(CAdvButton)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point); //
//
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
//
//
afx_msg void OnTimer(UINT nIDEvent);
//}}AFX_MSG
//处理 ON_WM_TIMER消息
//消息映射
//{{AFX_MSG_MAP(CAdvButton)
ON_WM_CREATE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_TIMER()
//}}AFX_MSG_MAP
WM_CREATE消息当创建窗口时被触发,其响应函数为 OnCreate。
WM_LBUTTONDOWN消息当用户鼠标左键按下时被触发,其响应函数为
OnLButtonDown。WM_ LBUTTONUP消息当用户鼠标左键抬起时被触发,其响应函数
为 OnLButtonUp。WM_MOUSEMOVE消息当用户鼠标移动时被触发,其响应函数为
OnMouseMove。WM_TIMER消息当计时器到达时被触发,其响应函数为 OnTimer。
再利用 ClassWizard覆盖父类中的两个关键的虚函数:
//{{AFX_VIRTUAL(CAdvButton)
public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
protected:
virtual void PreSubclassWindow();
//}}AFX_VIRTUAL
其中对于所有的对于按钮的绘制工作都是在 DrawItem函数中完成的。
3.3.2添加创建按钮控件代码
按钮的创建分两步完成。首先,调用构造函数对按钮对象进行初始化;其次,调用
Create函数创建按钮。
在构造函数中,对所有成员变量进行初始化。实现代码如下:
//构造函数
CAdvButton::CAdvButton()
{
//初始化 m_ClientRect
m_ClientRect.left
m_ClientRect.top
= 0;
= 0;
m_ClientRect.right = 0;
m_ClientRect.bottom= 0;
m_ClientRgn.DeleteObject();
//删除区域对象
m_ClientRgn.CreateEllipticRgnIndirect(&m_ClientRect);
//创建椭圆区域
m_State = 0;
m_Point.x = m_Point.y = 0;
m_IsTimerOn = FALSE;
}
重载父类中的 Create虚函数。实现代码如下:
//重载父类 Create函数
BOOL CAdvButton::Create(LPCTSTR lpszCaption,DWORD dwStyle,const RECT& rect,
CWnd * pParentWnd,UINT nID)
{
return CButton::Create(lpszCaption, dwStyle, rect, pParentWnd, nID);
}
3.3.3设置按钮形状、外观、颜色、标题
要创建用户自绘制按钮,必须将按钮的风格设为 BS_OWNERDRAW。因为只有设
置了这一属性,那么当按钮控件的可见部分需要重绘时, Windows才会调用
CAdvButton::DrawItem函数,用户定义的对按钮的绘制工作才会有效。否则, DrowItem
函数将不会被调用。
PreSubclassWindow函数在窗口被创建之前就被调用,因此,在 PreSubclassWindow
函数中,将按钮的风格设为 BS_OWNERDRAW。实现代码如下:
void CAdvButton::PreSubclassWindow()
{
//修改按钮控件风格
ModifyStyle(0, BS_OWNERDRAW|BS_PUSHBUTTON);
CButton::PreSubclassWindow();
}
如果要使得按钮能对鼠标的移动与点击作出不同的变化,那么按钮就需要时刻知道
鼠标的位置与动作。所以,就必须在鼠标的点击、弹起及移动消息的响应函数里填加相
应的代码,以获取鼠标的位置与动作。
在鼠标左键按下时,得到按钮窗口客户区域的屏幕坐标位置和鼠标的屏幕坐标位
置。当鼠标坐标位置落于窗口客户区域内,且当前按扭控件处于非选中状态时,将按钮
状态标帜设为选中状态,即将 m_State设为 2。接着,调用 Invalidate函数,使客户区无
效,框架会自动调用 DrawItem函数,重绘客户区。其实现代码如下:
Visual C ++简明教程
//当鼠标在按钮的客户区内按下时,改变按钮状态
void CAdvButton::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CRect rect;
GetWindowRect(&rect);
GetCursorPos(&m_Point);
//得到按钮客户区域的屏幕坐标位置
//得到鼠标的屏幕坐标位置
if((rect.PtInRect(m_Point))&&(m_State != 2))
{
m_State = 2;
Invalidate();
//
//重绘客户区
}
CButton::OnLButtonDown(nFlags, point);
}
在鼠标左键抬起时,得到按钮窗口客户区域的屏幕坐标位置和鼠标的屏幕坐标位
置。当鼠标坐标位置落于窗口客户区域内,且当前按扭控件处于选中状态时,将按钮状
态标帜设为非选中状态,即将 m_State设为 1。接着,调用 Invalidate函数,使客户区无
效,框架会自动调用 DrawItem函数,重绘客户区。其实现代码如下:
//当鼠标在按钮的客户区内弹起时,改变按钮状态
void CAdvButton::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CRect rect;
GetWindowRect(&rect);
GetCursorPos(&m_Point);
//得到按钮客户区域的屏幕坐标位置
//得到鼠标的屏幕坐标位置
if((rect.PtInRect(m_Point))&&(m_State != 1))
{
m_State = 1;
Invalidate();
//
//重绘客户区
}
CButton::OnLButtonUp(nFlags, point);
}
在用户移动鼠标时,如果计时器没有启动,则启动计时器,并将计时器启动标帜
m_IsTimerOn设为 TRUE。其实现代码如下:
//当鼠标在按钮的客户区内移动时,启动计时器
void CAdvButton::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if(!m_IsTimerOn)
{
//如果计时器没有启动
SetTimer(1000,100,NULL); //启动计时器
m_IsTimerOn = TRUE; //
}
CButton::OnMouseMove(nFlags, point);
}
当计时器消息当达时,其响应函数 OnTimer将被调用。在 OnTimer函数中,首先获
得按钮窗口的客户区域的屏幕坐标位置和鼠标的屏幕坐标位置。
当鼠标位置落于按扭控件客户区域时,则说明鼠标是在按钮的客户区内移动。如果
按扭控件处于非焦点和非选中状态,则将按扭控件状态设为获得焦点状态。调用
Invalidate函数,使窗口无效。框架自动调用 DrawItem函数重绘按钮客户区。
当鼠标位置没有落于按扭控件客户区域时,则说明鼠标已经移出了按钮的客户区。
如果按钮没有处于默认状态,则将按钮设为默认状态。调用 Invalidate函数使按钮客户
区无效。框架自动调用 DrawItem函数,重绘按钮客户区。
并且如果鼠标已经移出了按钮的客户区,则消毁计时器,并将计时器的开启标帜
m_IsTimerOn设为 FALSE。
OnTimer函数的实现代码如下:
//计时器消息的响应函数
void CAdvButton::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
CRect rect;
GetWindowRect(&rect);
GetCursorPos(&m_Point);
//得到按钮客户区域的屏幕坐标位置
//得到鼠标的屏幕坐标位置
if(rect.PtInRect(m_Point))
{
//如果鼠标在按钮的客户区内
if((m_State != 1)&&(m_State != 2)) {
m_State = 1;
Invalidate();
//
}
}
else {
//如果鼠标已经不在按钮的客户区内了
if(m_State != 0) {
m_State = 0;
Invalidate();
}
//重绘客户区
KillTimer(nIDEvent); //销毁计时器
m_IsTimerOn = FALSE;
Visual C ++简明教程
}
CButton::OnTimer(nIDEvent);
}
下面来实现客户区的绘置函数 DrawItem。DrawItem函数是一个虚函数,它是在按
钮控件上进行绘制操作的关键函数。当按扭的风格具有 OWNERDRAW属性时,如果按
钮的可见区域需要重绘时,框架会自动调用 DrawItem函数。其参数 lpDrawItemStruct
包含了在按钮客户区域绘图所需的所有必要信息。
在 DrawItem函数中,首先得到窗口的的有效矩形区域,在此矩形区域内创建椭圆。
调用 SetWindowRgn函数,设置窗口的有效区域为椭圆。
从参数 lpDrawItemStruct结构中得到按钮控件客户区域的设备环境变量指针。根据
按钮当前状态,创建不同的画笔。调用设备环境类的成员函数,设置背景模式为透明,
选择画笔,在按钮客户区内绘制椭圆及显示文本。其实现代码如下:
//这按钮控件客户区的绘置函数,也是实现所有高级控件的关键
void CAdvButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
GetClientRect(&m_ClientRect);
m_ClientRgn.DeleteObject();
//得到窗口的的有效矩形区域
//
m_ClientRgn.CreateEllipticRgnIndirect(&m_ClientRect);
//在矩形区域内创建椭圆
//设置窗口的有效区域为椭圆
SetWindowRgn(m_ClientRgn,FALSE);
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC); //得到按钮控件客户区域的设备
环境变量指针
CPen* pPen = NULL;
switch (m_State)
//根据按钮不同的状态,创建不同的画笔
{
case 0:
pPen = new CPen(PS_SOLID,1,DefaultColor);
break;
case 1:
pPen = new CPen(PS_SOLID,1,FocusColor);
break;
case 2:
pPen = new CPen(PS_SOLID,1,SelectColor);
break;
case 3:
pPen = new CPen(PS_SOLID,1,DesiableColor);
break;
}
pDC->SetBkMode(TRANSPARENT); //设置背景模式为透明
pPen = pDC->SelectObject(pPen);
pDC->Ellipse(&m_ClientRect);
//
//在按钮客户区内绘制椭圆
pPen = pDC->SelectObject(pPen);
if(pPen) delete pPen;
//
LPTSTR pCaption = new char[MAXCAPTIONLEN];
//
int iLen = GetWindowText(pCaption,MAXCAPTIONLEN);
pDC->SetTextColor(TextColor);
//指定文本颜色
//绘制文本,作为按钮标题
pDC->DrawText(pCaption,iLen,&m_ClientRect,DT_SINGLELINE|
DT_CENTER|DT_VCENTER);
}
通过上面的代码,按钮就已经具有了对鼠标不同的位置和动作改变不同的颜色。并
且,按钮的客户区域已经是一个椭圆,而不再是一个矩形。正是下面的代码将按钮的客
户区域设定为椭圆形:
GetClientRect(&m_ClientRect);
m_ClientRgn.DeleteObject();
//通到窗口的的有效矩形区域
//
m_ClientRgn.CreateEllipticRgnIndirect(&m_ClientRect);
//在矩形区域内创建椭圆
//设置窗口的有效区域为椭圆
SetWindowRgn(m_ClientRgn,FALSE);
至此,一个完整的高级按钮类就全部完成了。
3.4实现高级编辑控件类
利用 ClassWizard添加一个新类。如图 3-12所示:
图 3-12添加 CAdvEdit类
添加的新类命名为 CAdvEdit,其父类为 CEdit。下面就在此类的基础上,实现高级
编辑控件。
3.4.1添加成员变量和成员函数
为 CAdvEdit类添加一个字符串类型的成员变量 m_Caption,用来记录编辑框中的文
本内容。其代码如下:
//CAdvEdit.h头文件
Visual C ++简明教程
public:
CString m_Caption; //编辑框文本
利用 AppWizard添加消息函数 OnPaint。此函数是 WM_PAINT消息的响应函数,
当编辑框可见客户区需要重绘时,此消息会被触发,框架会自动调用 OnPaint函数。
并且利用 AppWizard添加两个 public类型的成员函数,分别用来绘制编辑控件客户
区和设置编辑控件的显示文本。
实现代码如下:
public:
void OnDraw(); //绘制编辑控件客户区
void OnDisplay(LPCTSTR lpszStr);
protected:
//设置编辑控件显示文本
//{{AFX_MSG(CAdvEdit)
afx_msg void OnPaint();
//}}AFX_MSG
//WM_ON_PAINT消息的响应函数
3.4.2添加编辑控件代码
在 OnDisplay函数中设置编辑框的显示文本。 OnDisplay函数的参数 lpszStr为字符
串类型,它包含了要设置的显示文本的内容。在 OnDisplay函数中将参数 lpszStr的值符
给成员函数 m_Caption,再调用 OnDraw函数将其显示出来。实现代码如下:
//设置编辑控件文本
void CAdvEdit::OnDisplay(LPCTSTR lpszStr)
{
m_Caption = lpszStr;
OnDraw();
}
在 OnPaint函数中调用自定义函数 OnDraw。实现代码如下:
//WM_ PAINT消息的响应函数
void CAdvEdit::OnPaint()
{
CPaintDC dc(this); // device context for painting
OnDraw();
}
在 OnDraw函数中,在编辑控件客户区域内绘制文本。首先,得到编辑控件客户区
的矩形区域;其次,得到编辑控件客户区的设备环境变量;接着,用指定的画刷填充客
户区,并且用指定的颜色绘制显示文本。
实现代码如下:
//绘制编辑控件客户区
void CAdvEdit::OnDraw()
{
CRect rect;
GetClientRect(&rect); //得到客户区矩形区域
CDC* pDC = GetDC();
//得到编辑控件设备环境变量
pDC->SetBkMode(TRANSPARENT); //设置背模式为透明
CBrush * pBrush = new CBrush(RGB(255,255,255)); //创建白色画刷
pDC->FillRect(&rect,pBrush);
//用画刷填充客户区
pDC->SetTextColor(RGB(92,92,92));
//设置文本颜色
//绘制文本,用指定的颜色和字体
pDC->DrawText(m_Caption,rect,DT_SINGLELINE|DT_VCENTER|DT_RIGHT);
}
3.5对话框界面设计
在实现在 CAdvButton和 CAdvEdit之后,现在来实现主对话框界面功能。
由于主对话框上控件按钮较多,而且要实现动态扩展功能和菜单功能,所以要添加
的成员变量和成员函数较多。因此,不在此全部列出。下面仅对其中重要的成员变量和
函数加以说明。
主要成员变量:
//CCalculatorDlg.h头文件
CButton
m_DspStatic;
CAdvEdit m_DspEdit;
//显示计算结果的编辑框
CMenu *
BOOL
m_Menu;
//对话框菜单按钮
m_IsExtend;
//标志对话框是否已扩展
主要成员函数:
//CCalculatorDlg.h头文件
//{{AFX_VIRTUAL(CCalculatorDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); //数据交换函数
//}}AFX_VIRTUAL
virtual BOOL OnInitDialog();
//虚函数,可覆盖用来进行用户初始化操作
virtual void OnOK(); //虚函数,覆盖用来屏蔽 Enter操作
//{{AFX_MSG(CCalculatorDlg)
//响应消息 ON_WM_CTLCOLOR,用以修改对话框及其控件颜色
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
afx_msg void OnPaint();
//响应消息 WM_ON_PAINT
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); //响应消息 WM_ON_CREATE
//}}AFX_MSG
除以上的主要成员外,还需要对每个按钮控件定义一个 CAdvButton的对象与之相
关联,并为对每个按钮控件建立一个成员函数来响应其 EN_CLICKED消息。由于函数
较多,不在此列举,请读者查看光盘中的示例代码。
Visual C ++简明教程
3.5.1加载菜单资源
在 3.2.2节中,已经为工程新建了一个菜单资源 IDR_MENU。现将其添加到计算器
对话框上。利用 CMenu类的 LoadMenu函数,将菜单资源加载到内存中。再调用 SetMenu
函数,将菜单添加到对话框上。实现代码如下:
//初始化对话框函数
BOOL CCalculatorDlg::OnInitDialog()
{
CDialog::OnInitDialog();
//调用父类的初始化代码
//其它的初始化代码
m_Menu = new CMenu;
//
m_Menu->LoadMenu(IDR_MENU);
//加载菜单资源模板
//将菜单添加到对话框
return TRUE; // return TRUE unless you set the focus to a control
SetMenu(m_Menu);
}
3.5.2关联控件与对象
在 CCalculatorDlg类的声明中,已经为编辑框、静态框及每一个按钮声明了相应类
型的对象与之对应。但这些控件与对象的关联工作是在 DoDataExchange函数中利用
DDX_Control宏来完成的。宏 DDX_Control需要三个参数,即 CDataExchange类型的指
针,控件 ID,相应类型的对象。实现代码如下:
//数据交换函数
void CCalculatorDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CCalculatorDlg)
DDX_Control(pDX, IDC_DSPSTATIC, m_DspStatic); //静态框
DDX_Control(pDX, IDC_DSPEDIT, m_DspEdit);
//编辑框
//将按钮控件与 CAdvButton对象相关联
DDX_Control(pDX, BTN_0, m_AdvButton0);
DDX_Control(pDX, BTN_1, m_AdvButton1);
DDX_Control(pDX, BTN_2, m_AdvButton2);
DDX_Control(pDX, BTN_3, m_AdvButton3);
DDX_Control(pDX, BTN_4, m_AdvButton4);
DDX_Control(pDX, BTN_5, m_AdvButton5);
DDX_Control(pDX, BTN_6, m_AdvButton6);
DDX_Control(pDX, BTN_7, m_AdvButton7);
DDX_Control(pDX, BTN_8, m_AdvButton8);
DDX_Control(pDX, BTN_9, m_AdvButton9);
DDX_Control(pDX, BTN_10, m_AdvButtonPoint);
DDX_Control(pDX, BTN_11, m_AdvButtonEqu);
DDX_Control(pDX, BTN_12, m_AdvButtonAdd);
DDX_Control(pDX, BTN_13, m_AdvButtonSub);
DDX_Control(pDX, BTN_14, m_AdvButtonMul);
DDX_Control(pDX, BTN_15, m_AdvButtonDiv);
DDX_Control(pDX, BTN_16, m_AdvButtonClear);
DDX_Control(pDX, BTN_17, m_AdvButtonSqrt);
DDX_Control(pDX, BTN_18, m_AdvButtonReverse);
DDX_Control(pDX, BTN_19, m_AdvButtonSin);
DDX_Control(pDX, BTN_20, m_AdvButtonCos);
DDX_Control(pDX, BTN_21, m_AdvButtonTan);
DDX_Control(pDX, BTN_22, m_AdvButtonSqu);
DDX_Control(pDX, BTN_23, m_AdvButtonCub);
DDX_Control(pDX, BTN_24, m_AdvButtonPow);
DDX_Control(pDX, BTN_25, m_AdvButtonExp);
DDX_Control(pDX, BTN_26, m_AdvButtonLn);
DDX_Control(pDX, BTN_27, m_AdvButtonLog);
//}}AFX_DATA_MAP
}
3.4.3实现对话框扩展功能
首先,在 CCalculatorDlg::OnCreate函数中,设定对话框的初始大小与位置。OnCreate
是 WM_ON_CREATE消息的响应函数,该函数在对话框创建时被触发。此时,窗口还
没有完全被创建好,因此,不可以在此初始化一些完全基于窗口的操作。可以在这个对
话框中进行窗口风格修改,位置设置等操作。其参数 lpCreateStruct中包含了创建窗口所
需的所必需信息。在此函数中修改对话框大小后,对话框就会以指定的大小显示,而不
是以对话框板中建立的大小显示。实现代码如下:
int CCalculatorDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialog::OnCreate(lpCreateStruct) == -1)
return -1;
CRect rect;
GetWindowRect(&rect);
//得到对话框的窗口区域矩形
//指定窗口大小与位置;宽为 232像素,高度不变
SetWindowPos(&wndTop,0,0,232,rect.Height(),SWP_NOMOVE|SWP_NOZORDER);
// TODO: Add your specialized creation code here
return 0;
}
其次,添加菜单项 ID_EXTEND的响应函数 OnExtend。在 OnExtend函数中,首先
判断当前对话框状态,即是否已经被扩展。
如果对话框已被扩展,则收缩对话框。首先得到对话框的当前位置,将其指定为新
的宽度,但高度维持不变。再将其中的编辑控件和编辑控件外的静态框收缩到合理的位
置。最后将菜单项 ID_EXTEND的显示文本设置为“扩展”,将表示对话框是否扩展的
Visual C ++简明教程
标帜变量 m_IsExtend设置为 FALSE。
如果对话框为非扩展,则扩展对话框。首先得到对话框的当前位置,将其指定为新
的宽度,但高度维持不变。再将其中的编辑控件和编辑控件外的静态框收缩到合理的位
置。最后将菜单项 ID_EXTEND的显示文本设置为“收
展开阅读全文