【摘要】本文适合已经完整学习了C++面向对象机制,但在开发窗体程序方面还是零基础的同学。通过本文的引导进行实践体验,目的是消除同学们开发窗体程序的神奇感,为下一步的自学找到感觉。同一时候,能更深入地体会到编程基本功的根源所在,在今后能自觉地学好专业基础课,而不是仅仅浮躁地追求开发平台和表面的技能。文章最后给出进一步实践的建议。

【相关博文】C++“窗体”程序设计启蒙(之中的一个)

  学习进程已经到了C++程序设计的尾声。同第一次体验窗体不同,我们已经具备了相当的“经验”,每周3-5个任务,近两万行的代码不是白做的。美中不足的是,我们面对的仍然是黑框框(虽然同学们已经会把黑框框改成各种颜色、字体的彩框框)。我们已经深刻领会了C++语言中的各种机制,而且能够将之用于各种应用场合。

  如今,我们将再次体验窗体程序设计,看到自己定义的类怎样參与到实际的项目中来。由于学习了面向对象程序设计,我们还能够看到利用向导生成的程序原来也是建立在OOP的基础的,程序中对话框、编辑框、button等均是MFC中例的实例,MFC中提供的类是能够被用户程序继承来使用的。这就是软件project中强调的尽可能利用已有“类库”的最生动的案例。

  闲言碎语不讲了,先看这次体验的案例——求三角形的面积。



  一、三角形类

  第5周实验的任务一,我们已经设计过一个比較完整的三角形类,主要代码例如以下所看到的(main()函数和类的showMessage()成员函数就不写了,这是给黑框框准备的):

class Triangle
{
public:
Triangle(){a=1;b=1;c=1;} //设计默认构造函数,即不指定參数时,默认各边长为;
Triangle(double x, double y, double z) {a=x; b=y; c=z;} //使用带參数构造函数,即Triangle(doublex, double y, double z),三边长在调用时由实參直接给出
double perimeter(void);//计算三角形的周长
double area(void);//计算并返回三角形的面积
private:
double a,b,c;//三边为私有成员数据
}; double Triangle::perimeter(void)
{
return (a +b + c);
} double Triangle::area(void)
{
double s =(a + b + c) / 2;
return sqrt(s * (s - a) * (s - b) * (s - c));
}

  写出这点代码已经是小case,后面运算符重载、继承、多态、虚函数等真功夫还没用呢!

  以下开发窗体版程序。和第一次的体验不同,这次的平台选用VS2008。、



  二、窗体程序的开发

  1、新建MFC应用程序

  选择菜单->文件->新建,在“项目类型”中选择“MFC”,右边的“模板”中选“MFC应用程序”,然后在项目“名称”处为项目命名,如图1所看到的:

   (图1)

  点击“确定”后,见图2:

   (图2)

  再点“下一步”,见图3:

   (图3)

  在“应用程序类型”部分,选择“基于对话框”(我们熟悉的“记事本”是典型的单文档应用程序,多文档应用程序形如Word2003。这两种应用在现实中更有用,但本文仅仅体验简单的基于对话框的应用程序。)

  就本文的应用而言,能够点击“完毕”了。只是做为体验而言,你能够继续“下一步”看看,只是在随后的界面中,不要改变默认的选项。

  当最后点击“完毕”之后,在出现的界面上就能够安排所须要的控件了。

  2、开发界面

  先认识一下例如以下的设计界面(图4),再讲怎样在界面上安排控件。

   (图4)

  图中的(1)-(5)各自是(请将(2)和(3)点开看一看):

  (1)解决方式资源管理器:当中列出了组成项目的全部文件,我们还将会添�自己写的“头文件”和“源文件”;

  (2)类视图:当中列出了项目中出现的全部类,能够查看这些类的数据成员、成员函数,以及这些类的“基类型”。(建议一定要看一看,这对理解我们刚刚学过的抽象类的理解非常有帮助。例如以下图是逐级打开CtriangleApp类的基类,最后查看到顶级基类CObject的情形。~CObject()是个虚函数,是虚析构函数,准确地讲,还是纯虚函数,因而CObject是抽象类,回想或复习我们在多态性和虚函数部分的内容,回想当时提出的在软件project方面的考虑,……)

   (图5)

  话题再回到图4。

  (3)资源视图:列出了项目中的对话框、图标等资源。在其它类型的应用程序中,像菜单、工具栏等也是作为资源出现的。应用程序开发过程须要编辑各种资源。当然,本文不将此作为体验内容。

  (4)属性:在设计中能够改动对话框、控件等对象的属性(实则相应的就是对象的数据成员);

  (5)工具箱:当中包含了常见应用程序界面中须要的各种“控件”(深刻理解:控件是MFC中已经定义好的供人机交互使用的类,将控件“拖”到界面上的动作,将相应由类实例化出其一个对象。如:用于文本编辑的控件 来源于MFC中定义的CEdit类,在对话框中“放置”一个Edit Control控件,即是实例化一个CEdit类的对象。)

  在你开发程序的过程中,(1)-(5)是时时须要用到的部件。可是,有时界面上并不能找到。假设哪一个东东“失踪”了,首先要看看整个界面,是否“停靠”在了哪个边缘。另外,点击“视图”菜单,如图6,你能够在这里找到你的所需。

   (图6)

  话题扯开了一些,以下接着进行设计。



  3、在界面上布置控件

  回到图4的界面,从“工具箱”中找到“Static Text”(静态文本)控件,拖到对话框中;在“属性”中,将Caption属性改为“a”(理解:Caption为该类的一个数据成员),如图7所看到的:

   (图7)

  用同样的方法,添�其它必要的控件(用于输入的编辑框控件Edit Control和button控件Button),并删除向导自己主动提供的其它控件后,结果如图8所看到的:

   (图8)

  提示一下,假设控件位置用鼠标拖着老对不齐,在菜单中有“格式”,当中的对齐工具能够帮忙(看看“对齐”)。

  接着要做的工作是,在应用程序中加入�成员就是,并将之与各个编辑框“联系”起来。以a后面的那个编辑框为例:选中编辑框,点鼠标右键,选“加入�变量(B)…”,然后,出现了“加入�成员变量向导”窗体,如图9所看到的,将“类别”改为value,变量类型选作double,而变量名为m_a(或者你喜欢的其它标识符)。

  (图9)

  相同的方法,对其余几个编辑框分别加入�变量,变量名分别中m_b、m_c和m_area。

  为编辑框设置与之联系的变量的意义在于,编辑框中输入的值将记录在对应的变量中,我们通过变量,就能够訪问编辑框中输入的值,也能够将计算得到的变量的值显示到编辑框中。换句话说,搭建起了程序中用到的变量,和窗体中的控件之间的桥梁。

  在项目中添�用户自己定义代码后,我们再设置点击“求面积”后要运行的代码。



  4、写入用户自己定义的代码

  须要将我们自己写的善于三角形类的代码添�项目。

  在“(1)解决方式资源管理器”栏中,在“头文件”处点击右键,选“加入�->新建项”,在项目中加入一个头文件(文件名称如:MyTriangle.h),内容是类的声明:

class Triangle
{
public:
Triangle(){a=1;b=1;c=1;}
Triangle(double x, double y, double z) {a=x; b=y; c=z;}
double area(void);
private:
double a,b,c;
};

  添�头文件的界面如图10所看到的:

   (图10)

  再在“源文件”处点击右键,选“增�->新建项”,在项目中添�一个源文件(文件名称如:MyTriangle.cpp),内容是类中成员函数的实现(添�#include stdafx.h的理由能够临时忽略,其它两个包括文件应该懂):

#include "stdafx.h"
#include <Cmath>
#include "MyTriangle.h"
double Triangle::area(void)
{
double s =(a + b + c) / 2;
return sqrt(s * (s - a) * (s - b) * (s - c));
}

  将类的声明放在头文件里,而实现的代码分放在还有一个源文件里,是项目开发中的一般做法,要学会和习惯于这样做。显然,本例中这么一点代码就占一个文件显得夸张了。

  请体会:对一个应用而言,这些用户自己定义的代码是核心。用术语讲,叫做“业务逻辑”。



  5、最后冲刺

  在图8所看到的的界面上,选择“求面积”button并双击鼠标,出现了以下的窗体(图11)

   (图11)

  此处,须要输入当点击button后要运行的代码。输入后的代码是:

void CtriangleDlg::OnBnClickedButton1()
{
// TODO: 在此加入�控件通知处理程序代码
UpdateData(); //将把界面上各控件输入的值“捕获”到与之关联的变量中
Triangle t1(m_a,m_b,m_c); //定义三角形对象
m_area=t1.area(); //求面积
UpdateData(FALSE); //用m_area的值更新界面上相应的控件的值并实现显示
}

  另外,在triangleDlg.cpp的開始处要写入“#include"MyTriangle.h"”,这个你应该懂,也要懂。

  最后,执行的结果如图12所看到的:

   (图12)



  三、依葫芦画瓢

  【任务0】随着阅读,重现上面的案例;

  【任务1】在以上演示样例基础,为应用程序添加�求周长的功能;

  【任务2】參考第8周任务3,设计分数类,并开发一个窗体式程序,能够完毕分数的四则运算。可供參考的一个界面如图13:

   (图13)



  四、进一步的回味

  1、改动控件属性

  在应用开发中,常须要改变控件的属性,以达到设计目的。建议将每类控件的属性都看一看,将可以理解的学会使用。

  比如,用于显示面积的编辑框仅仅起显示作用,不会用于输入,能够将其Disabled属性设为true,如图所看到的。在图14中,能够发现属性窗体部分的下方,显示对每种控件属性的含义,这是在学习中能够利用的有利条件。

   (图14)

  作为练习,试一下将显示面积的编辑框控件的Visible设置为false;Password设置为true,执行程序做些体会。

  2、理解代码及MFC

  请将项目中由向导自己主动生成的各个文件浏览一下,你将会发现我们确实已经学过了当中所包括的机制。

  以triangleDlg.h为例,定义的是CtriangleDlg 对话框。代码例如以下所看到的:

class CtriangleDlg : public CDialog
{
// 构造
public:
CtriangleDlg(CWnd* pParent = NULL); // 标准构造函数
// 对话框数据
enum { IDD = IDD_TRIANGLE_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
HICON m_hIcon;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedButton1();
double m_a;
double m_b;
double m_c;
double m_area;
};

  从代码中能够看到,这个应用程序中定义的CtriangleDlg类继承了CDialog类,当中的构造函数、虚函数等机制都有体现。还有,设置的m_a等几个变量,都是这个类的数据成员,而OnBnClickedButton1()为这个类的成员函数。

  再对比triangleDlg.cpp阅读,能够看到这个派生的类是怎样实现的。

  假设说阅读中的障碍,就是当中DoDataExchange等函数了。这些是在基类CDialog类,甚至CDialog类的基类中定义的了。这须要在长期的学习中,深入了解MFC及其机制。尤其是,理解和运用Windows编程中的消息机制。

  关于MFC中类的体系,可看图15。当中本文初步体验过的类,已经用红圈标注。



  (图15)

  进一步要看的书,包含Windows编程、MFC方面的书籍。还有不少书是基于VC++6.0或VS2008、VS2010等的案例开发教程,也能够作为阅读和实践的选择。

  五、结语

  看一个业界大牛的界面:

  

  对一个产品而言,虽然UI(用户界面)很重要,影响着产品的使用体验,甚至决定着产品的成败(想想苹果的产品)。对学习技术的同学,界面、窗体并不是应用的核心,核心仍在技术基础,须要优先解决编程能力的问题。在此基础上,再掌握开发平台。

   这是应用开发人员要走的路。

【相关博文】

C++“窗体”程序设计启蒙 (之中的一个)

寻找Bug记实:一个多重继承程序的查错

关于抄不抄作业的讨论

开放开发平台小全

函数返回值是否使用引用类型的问题:理解引用、返回值

使用常对象——为共用数据加装一个名为const的玻璃罩

开发经验和屁股的关系

大一学生C++博客地址

C++“窗体”程序设计启蒙(之二)的更多相关文章

  1. C++“窗体”程序设计启蒙

    [摘要]本文以C++菜菜鸟(仅仅须要学习了C++数据类型和控制结构就可以)为目标读者,用求解一元二次方程作为实例,展示窗体式程序的开发过程,获得初步体验.写作目的包含:(1)让学生通过模仿,开发出类似 ...

  2. 20145213《Java程序设计》实验二Java面向对象程序设计实验报告

    20145213<Java程序设计>实验二Java面向对象程序设计实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装,继承,多态 初步掌握UML建模 熟悉S.O. ...

  3. 20145206《Java程序设计》实验二Java面向对象程序设计实验报告

    20145206<Java程序设计>实验二Java面向对象程序设计实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O. ...

  4. 20145308刘昊阳 《Java程序设计》实验二 Java面向对象程序设计 实验报告

    20145308刘昊阳 <Java程序设计>实验二 Java面向对象程序设计 实验报告 实验名称 Java面向对象程序设计 实验内容 初步掌握单元测试和TDD 理解并掌握面相对象三要素:封 ...

  5. 20145317彭垚《Java程序设计》实验二

    20145317<Java程序设计>实验二Java面向对象程序设计实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O. ...

  6. 20145120 《Java程序设计》实验二实验报告

    20145120 <Java程序设计>实验二实验报告 实验名称:Java面向对象程序设计 实验目的与要求: 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握U ...

  7. 2018-2019-2 20175227张雪莹《Java程序设计》 实验二《Java面向对象程序设计》

    2018-2019-2 20175227张雪莹<Java程序设计> 实验二<Java面向对象程序设计> 实验报告封面 课程:Java程序设计 班级:1752班 姓名:张雪莹 学 ...

  8. 20175325 《JAVA程序设计》实验二《JAVA开发环境的熟悉》实验报告

    20175325 <JAVA程序设计>实验二<JAVA开发环境的熟悉>实验报告 一.实验报告封面 课程:Java程序设计 班级:1753班 姓名:石淦铭 学号:20175325 ...

  9. 20175316 盛茂淞 2018-2019-2 《Java程序设计》实验二 面向对象程序设计 实验报告

    20175316 盛茂淞 2018-2019-2 <Java程序设计>实验二 面向对象程序设计 实验报告 (一)单元测试 在 IDEA中我们把产品代码放在src目录中,把测试代码放在tes ...

随机推荐

  1. USACO 6.2 Packing Rectangles

    Packing RectanglesIOI 95 The six basic layouts of four rectangles Four rectangles are given. Find th ...

  2. 继承的基本概念: (1)Java不支持多继承,也就是说子类至多只能有一个父类。 (2)子类继承了其父类中不是私有的成员变量和成员方法,作为自己的成员变量和方法。 (3)子类中定义的成员变量和父类中定义的成员变量相同时,则父类中的成员变量不能被继承。 (4)子类中定义的成员方法,并且这个方法的名字返回类型,以及参数个数和类型与父类的某个成员方法完全相同,则父类的成员方法不能被继承。 分析以上程

    继承的基本概念: (1)Java不支持多继承,也就是说子类至多只能有一个父类. (2)子类继承了其父类中不是私有的成员变量和成员方法,作为自己的成员变量和方法.(3)子类中定义的成员变量和父类中定义的 ...

  3. win7 fiddler报“Creation of the root certificate was not successful”的问题

    cd "C:\Program Files (x86)\Fiddler2" makecert.exe -r -ss my -n "CN=DO_NOT_TRUST_Fiddl ...

  4. 《Android源码设计模式》--单例模式

    No1: 懒汉单例模式优缺点分析 public class Singleton{ private static Singleton instance; private Singleton(){} pu ...

  5. 在静态方法中应用spring注入的类

    最近在一次项目的重构中,原项目需要在静态方法中调用service,现在需要更换框架,service需要自动注入,无法再静态方法中调用 解决思路: 创建一个当前类的静态变量,创建一个方法,使用@Post ...

  6. gdg shell

    export TIMESTAMP=`date +%Y%m%d_%H%M%S`GDGFILE=file1_${TIMESTAMP}.txtsuffix=${GDGFILE#*_}prefix=${suf ...

  7. 1007 Maximum Subsequence Sum (25)(25 point(s))

    problem Given a sequence of K integers { N~1~, N~2~, ..., N~K~ }. A continuous subsequence is define ...

  8. android 视频

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 第一套完整版: 第二套完整版: 第三套完整版: 第四套完整版: 第五套完整版: ==== ...

  9. Qt Quick快速入门之qml与C++交互

    C++中使用qml对象,直接使用findChild获取qml对象,然后调用setProperty方法设置属性,当然必须在加载qml之后才能使用,不然findChild找不到对象,用法如下. engin ...

  10. ST-PUZZLE-2.0(一个益智游戏)

    注:未经博主允许不得转载. 原文链接:http://www.cnblogs.com/Blog-of-Eden/p/9060300.html 和 https://i-m-eden.github.io/2 ...