MFC学习笔记2---简单计算器
前言
学习了鸡啄米网页的前三部分后,我们就可以做一个小软件出来了,我选择先做一个计算器。
这是Win7系统自带的计算器:
为了提升成就感,我将计算器的大部分内容去除,于是就变成这样:
这样就只剩下了16个按钮和一个文本显示框,这样就简单多了!
新建一个MFC对话框应用程序
打开VS2010点击Start Page中的New Project(新建工程),或者菜单栏File -> New -> Project 弹出新建项目对话框,在左侧选择MFC,然后在中间选择MFC Application
在下面三个编辑框中输入工程名称及路径。VS2010会在Location中选择的路径下建立名为Solution Name的文件夹用来放置工程有关的所有文件包括源文件、资源文件、工程文件、调试记录、可执行文件等等,并在该文件夹下创建名为Name的文件夹放置程序员编写的.h和.cpp文件以及程序员建立的一些资源文件,当然这个文件夹可以有程序员根据自己的编程习惯进行一些修改。
下一步进入VS的新建MFC应用程序欢迎对话框:
下一步选择工程类型:
在1处选择基于对话框的应用程序,2处可以选择对话框使用的语言(我暂时未发现使用英文版对创建中文对话框的影响),3处去掉勾,我在这里不使用宽字符,4处我选择第二项,使用静态链接库。
接下来的几步都选择默认即可,也可以在设置完工程类型后直接点击Finish按钮完成创建工程。
这样,我们就得到了一个基于MFC对话框的应用程序模板
使用键盘快捷键Alt+Enter调出Properties窗口,Ctrl+Shift+C调出ClassView窗口,Ctrl+Alt+X调出Toolbox窗口,Ctrl+Shift+E调出资源窗口,这些都是在MFC中常用的一些窗口。
建立计算器外观框架
1、将MFC默认的控件删除:选中后按下键盘【Delete】
2、从Toolbox中拖出16个按钮控件(Button)输入内容并调整大小、位置
选中一个按钮控件,在Properties窗口中将Caption属性改为“1”,用类似的方法更改其他15个按钮内容;将其中一个按钮选中更改为合适的大小,按下键盘【Ctrl】,同时鼠标点击选中其他所有的按钮,最后点击选中已经调整好大小的按钮,放开键盘【Ctrl】,在工具栏找到[Make Same Width]和[Make Same Height](图片中红色方框)并点击;
通过图片中黄色方框中的几个工具将按钮位置调整好。
3、从Toolbox中拖出一个文本编辑框(EditControl),调整大小和位置,调整属性ModalFrame为True,ReadOnly为True
4、调整对话框的大小
这样就可以得到一个建议的计算器了,不过编译链接后只是显示出了计算器的外观而已,按下按钮并没有任何反应,这是因为还没有对按钮添加响应事件:
工程文件
创建应用程序后,VS2010会在工程下自动创建一些文件和资源:
如果在新建工程选择工程类型时选择简体中文,那么工程文件说明在ReadMe.txt中以中文的形式呈现给程序员。
同时,可见的这3个cpp源文件中,程序员并不会找到应用程序的入口函数WinMain(),这是因为VS已经封装好了,VS将入口函数放在appmodul.cpp中,为AfxWinMain()函数(可以按下F10键进入调试状态,自动定位到程序入口处)。
在ReadMe.txt中这样描述对话框类:
应用程序向导创建一个对话框类:
CalculatorDlg.h,CalculatorDlg.cpp - 对话框
这些文件包含 CCalculatorDlg 类。该类定义应用程序主对话框的行为。该对话框的模板位于 Calculator.rc 中,该文件可以在 Microsoft Visual C++ 中进行编辑。
在CalculatorDlg.h 中可以看到类CCalculatorDlg是基于类CDialogEx的,这样,我们可以编辑这个类从而使软件运行起来。
为对话框类添加变量及响应函数
1、打开类视图,为对话框类CCalculatorDlg添加变量:右键点击类名称:
出现添加成员变量的对话框,添加CString类型变量m_strCal用来储存用户输入的算式
2、右键点击编辑框,为控件添加变量Control类型CEdit变量m_edRes:
3、为类添加无返回值无参成员函数UpdateEditRes:
进入CalculatorDlg.cpp中进行编辑,代码如下:
void CCalculatorDlg::UpdateEditRes(void)
{
m_edRes.SetWindowTextA(m_strCal);
}
4、右键点击按钮“1”,添加事件处理程序OnBn1,点击Add and Edit转到CalculatorDlg.cpp中进行编辑:
代码如下:
void CCalculatorDlg::OnBn1()
{
// TODO: Add your control notification handler code here
m_strCal += "";
this->UpdateEditRes();
}
5、同理为其他按钮添加事件处理,除了“C”按钮和“=”按钮外其他事件处理基本相同。
6、“C”按钮用于初始化类成员变量:
void CCalculatorDlg::OnBnC()
{
// TODO: Add your control notification handler code here
m_edRes.SetWindowTextA("");
m_strCal = "";
}
7、“=”按钮由于计算最终用户输入的算式:(为了演示效果简化算法只进行一步运算)
void CCalculatorDlg::OnBnEqual()
{
// TODO: Add your control notification handler code here
CString str;
char *a;
int num[] = {, }; //储存左右两个操作数
int i = ;
char op; //储存操作运算符
while (!m_strCal.IsEmpty())//分析输入的字符串获得操作数和运算符
{
str = m_strCal.Left();
a = str.GetBuffer();
str.ReleaseBuffer();
switch (a[])
{
case '': num[i]=num[i]*+; break;
case '': num[i]=num[i]*+; break;
case '': num[i]=num[i]*+; break;
case '': num[i]=num[i]*+; break;
case '': num[i]=num[i]*+; break;
case '': num[i]=num[i]*+; break;
case '': num[i]=num[i]*+; break;
case '': num[i]=num[i]*+; break;
case '': num[i]=num[i]*+; break;
case '': num[i]=num[i]*+; break;
default: op= a[]; i++; break;
}
m_strCal = m_strCal.Mid();
}
int res; //储存运算结果
switch (op) //分析操作符,得到结果
{
case '+': res=num[]+num[]; break;
case '-': res=num[]-num[]; break;
case '*': res=num[]*num[]; break;
case '/': if(num[]==) AfxMessageBox("除数不能为"); else res=num[]/num[]; break;
}
CString strres;
strres.Format("%d", res); //将结果数拼装为字符串用于显示
m_edRes.SetWindowTextA(strres);
m_strCal = "";
}
8、界面优化
根据软件功能分析效果:只能有两个操作数,只能在两个操作数之间放置一个操作运算符,所以为了防止用户误操作,我们可以使用控件的EnableWindow函数控制按钮的可用与否:
为按钮“+” “-” “*” “/”添加变量m_bnPlus,m_bnMinus,m_bnMultiply,m_bnDivide:并调整他们的属性Disabled为True
在CCalculatorDlg类中添加bool类型变量m_bOp
然后在按钮“+” “-” “*” “/”消息函数中添加如下代码:
m_bnPlus.EnableWindow(FALSE);
m_bnMinus.EnableWindow(FALSE);
m_bnMultiply.EnableWindow(FALSE);
m_bnDivide.EnableWindow(FALSE);
m_bOp = true;
在按钮“C”消息函数中添加如下代码:
m_bnPlus.EnableWindow(FALSE);
m_bnMinus.EnableWindow(FALSE);
m_bnMultiply.EnableWindow(FALSE);
m_bnDivide.EnableWindow(FALSE);
在按钮“1”“2”“3”“4”“5”“6”“7”“8”“9”“0”中添加如下代码:
if (!m_bOp)
{
m_bnPlus.EnableWindow();
m_bnMinus.EnableWindow();
m_bnMultiply.EnableWindow();
m_bnDivide.EnableWindow();
}
在“=”按钮最开始处中添加如下代码:
if (m_strCal.IsEmpty())
{
return ;
}
在“=”按钮末尾处中添加如下代码:
m_bnPlus.EnableWindow(FALSE);
m_bnMinus.EnableWindow(FALSE);
m_bnMultiply.EnableWindow(FALSE);
m_bnDivide.EnableWindow(FALSE);
m_bOp = false;
这样一个最简单的计算器程序就做好了!!!
总结
整个对话框工程中运用了按钮和文本编辑框两类控件及其简单的成员函数,包括设置编辑框文本、设置按钮可用与否状态;为对话框添加成员变量、成员函数;一个调出消息框的函数AfxMessageBox函数;CString类的一些简单成员函数应用如CString:: IsEmpty(),CString:: Left(),CString::Mid(),CString:: Format()等。
最后,望各位同道中人给我提出宝贵意见
MFC学习笔记2---简单计算器的更多相关文章
- MFC 学习笔记
MFC 学习笔记 一.MFC编程基础: 概述: 常用头文件: MFC控制台程序: MFC库程序: 规则库可以被各种程序所调用,扩展库只能被MFC程序调用. MFC窗口程序: 示例: MFC库中类的简介 ...
- JSP学习笔记(三):简单的Tomcat Web服务器
注意:每次对Tomcat配置文件进行修改后,必须重启Tomcat 在E盘的DATA文件夹中创建TomcatDemo文件夹,并将Tomcat安装路径下的webapps/ROOT中的WEB-INF文件夹复 ...
- JAVA WEB学习笔记(三):简单的基于Tomcat的Web页面
注意:每次对Tomcat配置文件进行修改后,必须重启Tomcat 在E盘的DATA文件夹中创建TomcatDemo文件夹,并将Tomcat安装路径下的webapps/ROOT中的WEB-INF文件夹复 ...
- Spark学习笔记0——简单了解和技术架构
目录 Spark学习笔记0--简单了解和技术架构 什么是Spark 技术架构和软件栈 Spark Core Spark SQL Spark Streaming MLlib GraphX 集群管理器 受 ...
- Html学习笔记(二) 简单标签
标签的重点 标签的用途 标签在浏览器中的默认样式 <body>标签: 在网页上显示的内容 <p>标签: 添加段落 <hx>标签: 添加标题 标签一共有6个,h1.h ...
- Netty学习笔记(六) 简单的聊天室功能之WebSocket客户端开发实例
在之前的Netty相关学习笔记中,学习了如何去实现聊天室的服务段,这里我们来实现聊天室的客户端,聊天室的客户端使用的是Html5和WebSocket实现,下面我们继续学习. 创建客户端 接着第五个笔记 ...
- Java设计模式学习笔记(二) 简单工厂模式
前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 正文开始... 1. 简介 简单工厂模式不属于GoF23中设计模式之一,但在软件开发中应用也较为 ...
- MFC学习笔记1---准备工作
什么是MFC MFC,全称Microsoft Foundation Classes,微软基础类库,顾名思义,是微软的攻城狮们将一些常用的基础的Windows API 函数用C++的形式封装成类,简化程 ...
- CSS学习笔记09 简单理解BFC
引子 在讲BFC之前,先来看看一个例子 <!DOCTYPE html> <html lang="en"> <head> <meta cha ...
随机推荐
- OI常用的常数优化小技巧
注意:本文所介绍的优化并不是算法上的优化,那个就非常复杂了,不同题目有不同的优化.笔者要说的只是一些实用的常数优化小技巧,很简单,虽然效果可能不那么明显,但在对时间复杂度要求十分苛刻的时候,这些小的优 ...
- 正则表达式中 group groups区别
先看代码instance: 1 >>> a="123abc456" 2 >>> import re 3 >>> print(r ...
- SQL 2008建一个job
原文地址:http://blog.csdn.net/htl258/article/details/5543694 -- Author : htl258(Tony)-- Date : 2010- ...
- ActiveMQ从入门到精通(二)
接上一篇<ActiveMQ从入门到精通(一)>,本篇主要讨论的话题是:消息的顺序消费.JMS Selectors.消息的同步/异步接受方式.Message.P2P/PubSub.持久化订阅 ...
- angular 的跨域处理
angular 的跨域处理,由于不并不支持跨域处理,所以我们对他也是无可奈何,angular 的跨域处理,需要我们在服务器上进行处理,把请求的数据改成 * ,也就是,谁都可以请求数据: angular ...
- DAY 7 上午
一些图论的题目 BZOJ 3445 Roadblock 求出最短路,枚举每条边再跑一遍即可(科技为了我 代码: #include<bits/stdc++.h> using namespac ...
- 四十三、jenkins启动时报错:consider increasing the maximum size of the cache. After eviction approximately [10,239] KB of data
jenkins启动时报错: consider increasing the maximum size of the cache. After eviction approximately [10,23 ...
- python - del 方法
转自:http://blog.csdn.net/love1code/article/details/47276683 python中的del用法比较特殊,新手学习往往产生误解,弄清del的用法,可以帮 ...
- 阶段3 1.Mybatis_02.Mybatis入门案例_3.mybatis注解开发和编写dao实现类的方式
注解的用法 直接创建一个新的项目 下一步直接next 然后finish即可 把之前项目01里面的代码直接复制过来 复制到我们02的注解的工程中 把01项目导入的依赖也都粘贴过来 再把测试类复制过去 复 ...
- TCP中SYN洪水攻击
在查看TCP标识位SYN时,顺便关注了一下SYN Flood,从网上查阅一些资料加以整理,SYN洪水攻击利用TCP三次握手. 1.SYN洪水介绍 当一个系统(客户端C)尝试和一个提供了服务的系统(服务 ...