Visual C++ 2005编程
Windows编程其实不难。通过本书的全面学习,你会发现Visual C++ 2005会让你的Windows编程之路变得更加得宽敞。在你的学习之路上,唯一的障碍就是:在你接触Windows编程的各种细节之前,你必须要全面系统的学习C++的语言特性,特别是C++的面向对象设计技术。Visual C++ 2005提供了很多的Windows编程工具,而面向对象技术在这些工具中的作用是非常重要的。本书就将要带你学习、理解、掌握这些技术。
通过本章的学习,将使你对
C++
编写应用程序的一些基本概念有一个整体的了解。
Visual C++ 2005
集成开发环境(
IDE
)的各种操作都非常简单、易懂,因此将通过对
IDE
的快速浏览使你学习到大部分的操作。熟悉
IDE
的最好方法就是创建、编译、执行一个简单的程序来实践。到本章结束,你会学习到:
·
Visual C++ 2005
的主要组件是什么?
·
.Net
框架由什么组成?它具有什么优势?
·
什么是解决方案和工程以及如何创建?
·
控制台程序相关知识
·
如何创建、编辑程序?
·
如何编译、链接、执行
C++
控制台程序?
·
如何创建、执行基本的
Windows
程序?
好了,打开你的PC,启动Windows,在功能强大的Visual C++ 2005中开始我们的Window编程之旅!
.Net框架
.Net框架是微软.Net开发产品的中心概念,当然也包括Visual C++ 2005。.Net框架由两部分组成:应用程序执行宿主-通用语言运行时(CLR)和.Net框架类库集合。当代码在CLR环境下执行时,.Net框架类提供了函数功能支持,不管我们的代码是何种语言编写的。所以,使用C++、C#和其他支持.Net框架的语言编写应用程序都可以使用相同的类库。
在Visual C++ 2005中,可以编写两种基本不同类型的C++程序:一种是在本地计算机上直接运行的程序,此类C++符合ISO/ANSI语言标准,被称为本地C++程序;另一种就是在CLR控制下运行的程序,此类C++是ISO/ANSI语言标准的一个扩展,被称为C++/CLI。它们通常也称为CLR程序或者C++/CLI程序。
严格上说,.Net框架并不属于Visual C++ 2005,而是Windows操作系统为了帮助快速建立应用程序和Web Services而包含的组件。.Net框架不但在代码的可靠性、安全性上有非常大的优势,而且可以把C++和20多种支持.Net框架的语言进行混合编程。.Net框架的一个不利之处就是程序的性能下降,不过这种性能下降在大多数环境是可以忽略的。
通用语言运行时 (CLR)
对于很多用高级语言(Visual Basic、C#、C++等)编写的程序,它们都是在CLR标准环境中执行的。CLR已经作为通用语言规范(CLI)的一种被收录到欧洲计算机制造商协会(ECMA)标准ECMA-355之中,并在进一步完善以符合ISO标准(ISO/IEC 23271)。所以CLR是CLI的一种实现。这就是为什么CLR下的C++被写为C++/CLI,它是通用语言结构下的特殊C++。因此在其他操作系统上可能会看到实现CLI的C++/CLI编译器。
ECMA的所有标准信息都可以在
http://www.ecma-international.org
得到。ECMA-335现在可以免费下载。
CLI是虚拟机中一个非常重要的规范,它允许不同高级语言编写的应用程序,在不修改和编译源代码的条件下直接在不同的系统环境中执行。在编译高级语言时,CLI为虚拟机指定了标准的中间语言。在.Net框架中,中间语言被称为微软中间语言(MSIL)。中间语言的代码最后在执行时被及时映射到机器代码运行。当然,在CLI中间语言里的代码也可以在其他拥有CLI实现的环境被执行。
CLI
也定义一个通用的数据类型集,称为通用类型系统(
CTS
),可以被所有面向
CLI
实现的语言使用。
CTS
说明了如何在
CLR
中使用这些类型,同时包含了一个预定义类型集。
我们也可以定义自己的数据类型,定义的方法必须和CLR的说明保持一致。你会发现,通过标准化的数据类型系统描述数据,允许不同语言编写的组件采用统一的方法处理数据。同时让不同语言的组件集成到一个应用程序变为可能。
CLR主要通过两个方面大大提高了数据安全性和程序可靠性:一是动态内存的分配和释放都是自动完成的;二是在程序执行前程序的MSIL代码会进行全面的检测和验证。CLR也仅仅是CLI规范在Windows PC上的一种实现,在其他的操作系统和硬件平台上,肯定有不同的CLI实现。有时你会发现CLI和CLR两个术语被交替使用,尽管它们是非常明显的不同。CLI是标准规范,CLR是微软实现的一种CLI。
编写C++应用程序
在Visual C++ 2005中,可以开发的程序和组件类型非常多。正如在本章前面提到过的两种基本Windows程序类型:一种是代码和CLR一起执行;一种是代码直接编译为机器码然后在本地执行。在面向CLR基于窗口的程序中,可以采用.Net框架提供的Windows Forms作为GUI的基础。Windows Forms可以进行快速的GUI开发,因为它可以很方便的加入标准组件。同时完全自动生成代码。然后就可以按需修改生成的代码以满足我们不同的需要。
对于本地执行的代码,有多种操作方法。可以使用微软基础类(MFC)编写窗口程序的图形用户接口(GUI)。MFC封装了Windows操作系统的应用程序编程接口(API),实现了GUI的创建和控制,大大减少的程序开发的过程。如果是现在写的Windows API,它肯定被期望是面向对象的,但因为它比C++的出现早很多年,所以它不具有面向对象的特征。当然,谁也不会强逼你使用MFC,如果你想要更高的效率,那么自己用C++代码调用API函数吧!
与CLR一些执行的C++代码被称为托管C++,因为数据和代码都是CLR管理的。在CLR程序中,存储数据动态分配的内存被自动释放,因此它消除了本地C++程序中常出现的资源泄漏错误。而部分在CLR外执行的代码被称为非托管C++,CLR与它们的执行没有明显的关系。在非托管C++必须小心分配和释放内存的所有方面,非托管C++也被称为本地C++,因为它们是被直接编译为本地的机器码。
图
1
-
1
说明了开发
C++
应用程序的基本过程
图1-1
图1-1并没有覆盖所有的内容。应用可以既有托管C++又有非托管C++,因此没有必要把一种环境强制和其他的混入一起。当然,使用混合代码会有某些方面的损失。所以只在必要时选择混合编码,如转换已有的本地C++代码,让其和CLR一些执行时。在本地C++代码肯定不会有托管C++的一些固有特性。这些特性在托管、非托管代码组件通信相关方面可以很明显的看到。但是,当需要开发或者扩展已有的非托管代码,同时希望获得使用CLR的优势时,这种混合托管、非托管代码的能力是非常重要的。当然,在一个新的应用程序开始时就应该考虑是否希望使用托管C++。
学习Windows编程
在Windows下的交互式应用程序至少包含两个方面的内容:一是编码创建用户交互的图形用户接口(GUI);二是编码处理交互操作以实现应用程序的功能。Visual C++ 2005为Windows程序开发的这两个方面都提供了大量的辅助功能。正如你在本章后面看到的:可以不编写任何代码而创建一个带GUI的Windows程序。Visual C++ 2005会自动生成创建GUI的基本代码。但是,我们需要很好的理解这些自动生成的代码,因为我们要在这些代码的基础上进行扩展、修改以满足我们所需。而这项工作就要求全面、充分的理解C++。
考虑到上面提到的要求,所以最好先学C++――包括本地C++和C++/CLI两个语言版本,而暂时不涉及Windows编程相关的东西。在掌握了C++后,就可以快速的学习基于C++/CLI和C++的Windows编程。这就意味着学习C++的时候只是使用一些命令行相关的输入、输出程序。通过只使用命令行简单的输入、输出功能,我们就可以集中精力研究C++语言如何工作,避免一些不必要的GUI创建和控制。掌握C++以后,你就会发现用C++开发Windows应用程序是多么的容易,也是一种自然的过渡过程。
学习C++
Visual C++ 2005
全面支持两种不同标准定义的
C++
语言:
⑴
ISO/ANSI C++
标准,支持本地应用程序-非托管
C++
。此版
C++
在大多数的
计算机平台都支持。
⑵
C++/CLI标准,支持基于CLR的应用程序,是ISO/ANSI C++的扩展。
本书的第二章到第十章讲述C++语言。因为C++/CLI是ISO/ANSI C++的扩展,每章的第一部分讲述ISO/ANSI C++语言元素;第二部分讲述C++/CLI的附加特性。
编写C++/CLI程序可以充分利用.Net框架的作用,而这是ISO/ANSI C++程序不可能有的。虽然C++/CLI是ISO/ANSI C++的扩展,但是C++/CLI程序必须符合CLR的要求,因为这些程序要在CLR环境下执行的。也许看到这里,你心里也有了结论:ISO/ANSI C++提供的内存动态分配和释放与CLR是不兼容的。程序中必须使用CLR的内存管理机制,这就意味着必须用C++/CLI类而不能用本地C++类。
C++语言标准
美国国家标准委员会(ANSI)出版的ISO/IEC 14882文档定义了ISO/ANSI标准。到1998年,ISO/ANSI 标准C++已经制定了非常完善的C++语言版本。并且得到了大多数的硬件平台和操作系统的支持。用ISO/ANSI C++编写的程序可以很容易移植到其它相当的系统环境,但是即便如此,程序中使用的库函数会决定移植的困难度,特别是建立图形用户接口的函数。标准ISO/ANSI C++是很多专业程序员的首选,不但得到了广泛的支持,也是迄今为止功能最强大的编程语言。
C++语言标准可以在
http://www.iso.org
购买。
为了让C++能更好的支持ECMA-355定义的通用语言规范(CLI),C++/CLI扩展了ISO/ANSI标准C++。2003年,微软为了支持C++程序在.Net框架下执行,提出了一个初始的程序开发技术说明,它就成为了后来CLI标准的第一个版本。CLI和C++/CLI都是微软在.Net框架下提出的。当然,把它们标准化能加快在其他Windows环境中的实现。虽然C++/CLI是C++的扩展,必须注意的是如果希望程序完全在CLR的控制下运行,一些ISO/ANSI C++支持的特性将不能使用的。
在本地环境上,CLR有很多实质性的优势。让C++程序基于CLR执行,可以有更好的安全性。也能避免完全使用ISO/ANSI C++的一些潜在错误。CLR通过标准化目标编译环境消除了各种高级语言的不兼容。因此,以C++编写的模块可以和其他语言如C#、Visual Basic编写的模块组合在一起。
控制台程序
除了可以开发窗口程序,Visual C++ 2005允许编写、编译、测试纯粹的C++程序。它们没有窗口程序那么复杂的要求,是简单基于字符的命令行程序。在Visual C++ 2005中它们都是通过键盘、屏幕的字符模式进行交互,所以也称为控制台程序。
学习控制台程序,而不是Windows编程,这好像偏离了正轨。其实不然,学习C++的时候还不必涉及Windows编程的特殊技术,此时控制台程序是最好的方法。有许多非常简单的Windows程序代码,在学习C++的各种技术时不必为Windows的复杂而心烦意乱。因此本书前面讲述C++语言的章节,会介绍一些轻量级的控制台程序。然后才是很多重量级的Windows程序代码。
学习C++时,应该集中精力在C++的语言特征上,不必在意语言操作环境。在控制台程序中只有一个文本接口。此接口对于我们理解C++语言已经足够了,因此C++语言本身没有包含任何的图形功能。在使用微软基础类库(MFC)的本地C++程序,或者是CLR中Windows Forms编写窗口应用程序时,自然会介绍大量图形用户接口编程的知识。
常用的控制台程序主要有两种不同的程序类型:Win32控制台程序,编译为本地代码,与标准ISO/ANSI C++兼容;CLR控制台程序,基于CLR,可以使用C++/CLI的语言特性。
Windows编程思想(Concept)
编写Windows程序的捷径就是利用Visual C++ 2005提供的工具。Visual C++ 2005提供的工程创建工具可以自动生成各种类型的应用程序框架,包括窗口程序。用Visual C++ 2005开发程序的第一步就是创建工程。为了快速的了解这些工具,本章后面通过一些例子来详细介绍创建过程,包括Windows程序的框架。
Windows程序的结构与传统的从命令行执行的控制台程序不同,复杂很多。在控制台程序中,可以直接从键盘获取输入然后输出到命令行。而Windows程序只能通过Windows操作系统提供的函数来访问计算机的输入、输出设备。不允许直接访问硬件资源。Windows可以同时执行多个任务,Windows决定特定的输入操作,如鼠标点击和键盘按下,会被传送到哪个应用程序。以此通知相关的应用程序。因此Windows操作系统控制了用户的所有通信。
在Windows程序和用户之间的接口有很多,可以在任何时候进行大量不同的输入操作。用户可以选择任意多的菜单项,点击工具栏按钮,在应用程序窗口上点击鼠标。一个设计完善的应用程序可以在任何时候处理任意类型的输入,因为我们是无法提前知道程序将有什么样的输入操作发生。这些用户操作最先由操作系统接受,统一的处理为事件。和应用程序用户接口相关的事件通常引起程序部分特殊代码段的执行。因此程序是如何执行通常由用户的行为决定。以此方式运行的程序称为事件驱动程序。与传统的单一执行顺序程序不同。基于过程的程序,它的输入操作由代码控制,只有在程序允许的时候才有效。因此,Windows程序是由一些专门响应由用户行为引起的事件的代码片断组成。
图1-2中的每个方形块都是为了处理一个特殊事件而编写的特殊代码段。这些单独的代码块可能会让程序看起来很零碎,实际上连接这些代码块为一个程序整体是由操作系统完成的。可以把这些程序看作是提供特殊性能的自定义窗口。
在单独的程序中,为外部事件提供服务的模块,如菜单选择、鼠标点击等,通常都可以访问应用程序专门的通用数据集合。这些语言程序数据包含程序环境相关的信息,如编辑器中的字符串,棒球程序(游戏)中每个队员的得分记录,程序执行过程中发生的一些事件信息。这些共享的数据集可以让看似独立的程序模块用相同的、和谐的方式进行通信和操作。
Visual C++ 2005提供的应用程序向导可以生成Windows程序的每个基本单元,即使这个单元只有少量的几行代码。当然这几行代码可能变为很多代码。为了简化理解C++执行过程,需要一个尽可能简单的上下文环境。幸好Visual C++ 2005提供了现成的程序环境。
图1-2
什么是集成开发环境?
Visual C++ 2005的集成开发环境(IDE)功能非常强大,全面支持C++程序的创建、编译、链接和测试。也是学习C++语言的好环境(特别是和一些书籍配合使用)。
为了让编程C++程序更加容易,Visual C++ 2005设计、集成了很多辅助工具。本章会介绍部分工具。为了不让学习这些繁琐的工具、特征、选项变得枯燥,先看看IDE是如何工作的。然后随着本书来进一步了解IDE的知识。
系统组件
Visual C++ 2005中最基础的部分(也属于IDE)是编辑器、编译器、链接器以及库函数。它们是编写、执行C++程序最重要的基础工具。它们的主要作用有:
编辑器
编辑器提供了创建、编辑C++程序源代码的交互式环境。也提供了一些非常熟悉的常用工具如:剪切和粘贴。编辑器也提供颜色高亮以区别不同的颜色元素。它会自动的识别C++语言的基础关键字,然后根据它们的类型显示不同的颜色。这项功能不仅能让代码更可读,而且在输入这些语言关键字时如果发生错误,编辑器会很友好的作出提示。
编译器
编译器把源代码转换为对象代码,在编译过程中同时检查和报告错误信息。如果程序有无效、无法识别的代码,编译器都会报错误。结构上的错误如只有部分无法执行的程序代码同样报错。编译器输出的对象代码存储在对象文件中。输出的对象代码有两种类型。对象代码的扩展名通常是.obj。
链接器
链接器把编译器从源代码产生的模块文件组合在一起,从C++提供的程序库把需要的部分代码块加入,然后把所有的文件融合为可执行整体。链接器也是能检测错误的,如程序引用的代码丢失或者不存在。
程序库
程序库是一个简单的预先写好的程序集合,通过标准的、专业程序代码单元支持、扩展C++语言。所有的程序都可以引入到自己编写的代码完成一些常用的操作。Visual C++ 2005在不同的程序库中都通过程序实现了一些操作,这些程序可以大大的减少自己编写、测试这些代码的工作量。前面提到的.Net类库,还有其他的程序库,实现太多此处不便列举。本书会介绍一个最重要的程序库。
标准C++程序库定义了一个基础的函数集,这些函数可以在任何支持ISO/ANSI C++的编译器上运行。标准C++程序库实现了有大量的程序功能,包括数值计算(计算平方根和计算三角函数等),字符、字符串处理程序(字符分类和字符比较)等等很多。随着你掌握更多的ISO/ANSI C++知识,对标准C++程序库也会更熟悉的。当然也有支持ISO/ANSI C++扩展版的C++/CLI程序库。
微软基础类库(MFC)提供了对本地基于窗口的应用程序支持。MFC大大的减少了建立应用程序图形用户接口的工作量。在进一步研究C++的细微差别后,对MFC也就更熟悉。另一个程序库Windows Forms也实现了很多的工具程序,和MFC一样都减少了建立基于窗口的应用程序的工作量。它是在.Net框架下执行的。本书也会介绍如何用Windows Forms库开发应用程序。
如何使用IDE
本书所有的程序都是在Visual C++ 2005的IDE中开发执行的。启动Visual C++ 2005以后,会得到和图1-3类似窗口界面。
图1-3
图1-3左边的窗口是解决方案浏览窗口。右上角显示启动画面的窗口是编辑器窗口。底部是输出窗口。解决方案浏览器可以浏览每个文件、同时在编辑器中显示文件内容。也可以向程序添加文件。解决方案浏览器窗口有三个其他的切换页(图1-3中只显示了两个):类视图、资源视图和应用程序的属性管理。也可以通过View菜单选择不同页来进行显示。编辑器是输入、修改源代码和其他程序组件的窗口。底部的输出窗口在编译、链接程序时会显示一些消息。
工具栏选项
在工具栏区点击右键,可以自定义选择需要在Visual C++窗口中显示哪些工具栏。图1-4显示了右键弹出菜单列举的所有工具栏名称。所有当前显示的工具栏都会在菜单项前面显示选中标记。
图1-4
任何时候都可以通过这里定义需要显示的工具栏。图1-3中显示的工具栏有:Build、Class Designer、Debug、Standard和View Designermenu。在菜单左边的空白灰色区点击可以使工具栏显示。点击选中标记可以使工具栏隐藏。
不必为应用程序有时需要太多的工具栏而感到混乱。因为有些工具栏在需要时会自动的显示。所以默认的工具栏设置能满足大多数时候的需要。也许在开发程序的时候会觉得范围没有显示的工具栏很不方便,任何可需之时都可以通过工具栏区右键的菜单来改变工具栏设置。
和其他窗口应用程序一样,Visual C++ 2005的所有工具栏都有提示信息。在工具栏按钮上稍微的停顿,白色标签就会显示工具栏的作用。
工具栏停靠
可停靠工具栏可以通过鼠标拖动到窗口内任意方便的位置。如果是停靠在应用程序的四边,工具栏就处理停靠状态。外观和应用程序顶部的工具栏一样。顶部的标准工具栏上有一个磁盘图标、在一个双眼望远镜文件图标的右边有一个文本输入框。把鼠标放在标准工具栏上,按下鼠标左键,然后保存左键的按下状态,此时标准工具栏就如是一个单独的窗口,可以放在任何的地方。
拖动任何可停靠工具栏离开停靠位置时,会看到图1-5中标准工具栏一样的效果——一个小的封闭窗口,只是标题栏不同。这种状态下称为浮动工具栏。图1-3中看到的所有工具栏都是可停靠、可浮动的。所以可以用它们做停靠拖动试验。可以停靠工具栏在一些位置观察相反的外观状态。可以把可停靠工具栏停靠在主窗口的任何位置。
图1-5
Visual C++ 2005中工具栏使用的一些图标都比较通用。和其他一些窗口程序一样,不会给人很陌生的感觉。有时程序员不会重视Visual C++环境中按钮的确切含义。因此本书会在使用的时候单独介绍。
通常开发的每个程序都需要建立一个新的工程。着眼于工程的确切含义,理解工程定义机制能帮助学习Visual C++ 2005的IDE。
文档
关于Visual C++ 2005的资料有很多。微软开发者网络(MSDN)文档库不仅提供了关于Visual C++ 2005全面的、所有方面的参考资料。还有其他很多的开发资料。在按照Visual C++ 2005的时候,可以选择部分还是全部的MSDN文档。如果有足够的硬盘空间,强烈建议按照MSDN文档库。
浏览MSDN文档库可以用F1键。Help菜单下也有多个文档访问方法。在本章后面会看到,遇到编码错误时MSDN是一个非常有用的工具,它提供了足够的参考文档。
工程和解决方案
工程包含了组成各种类型程序所需的所有内容。可以是控制台程序、基于窗口的程序或者是其他类型。通常包含一个、多个存储代码的源文件,加上一些其他的辅助数据。工程的所有文件都放在工程文件夹。关于工程的一些其他详细信息存储在工程文件夹下以vcproj为后缀的XML文件中。工程文件夹下还包含一些其他的文件夹,用来存储编译、链接工程输出的文件。
解决方案顾名思义,代表一个特殊数据处理问题的解决方法,它建立了一种有效的集合所有程序代码、资源的机制。比如商务操作中的分布式顺序登陆系统,可能需要在一个解决方案中分别开发几个不同的工程程序。因此解决方案是存储一个、多个相关工程所有信息的文件夹。在解决方案文件夹下可以有多个的工程文件夹。关于解决方案的工程信息文件存储在两个文件中,分别以.slnand、.suo为后缀。创建工程时,如果没有选择把工程加入到某个解决方案中,系统会自动创建一个新的解决方案。
如果在创建工程时也创建了解决方案,就可以把其他的工程加入到这个解决方案中。你甚至可以把任何的工程都加入到此解决方案。在实践操作时,为了方便管理,只把和解决方案的相关一些工程添加到一起。一般在没有特殊原因的时候都应该给每个工程建立相应的解决方案。本书所有的例子工程都是单独的,都有自己的解决方案。
定义工程
在Visual C++ 2005中编写程序的第一步是创建工程:在主菜单的File -> New -> Project或者快捷键Ctrl+Shift+N。也可以创建一些包含代码的文件及其他组成程序的数据。在工程目录下的XML文件记录了工程中使用的一些Visual C++ 2005设置。这些文件都是由IDE自己进行维护,可以不过多关注它们。但是偶尔修改这些文件时需要注意。
到此,已经介绍不少的内容,现在通过一些实践操作来巩固这些知识。
实践——创建Win32工作台程序工程
下面讲述如何创建一个控制台程序工程。选择File -> New -> Project打开新建工程对话框,如图1-6:
图1-6
新建工程对话框左边的树形列表显示了可以创建的工程类型。在本例中选择Win32。选择不同的工程类型决定了应用程序向导会创建怎样的初始工程内容。新建工程对话框的右边显示出所有的子工程模板。应用程序向导会根据选择的模板创建工程的组成文件。点击新建工程对话框的OK按钮后,在下一个出现的对话框中可以自定义创建的文件。对大多数的工程、模板选项,都会自动的创建工程的基础源代码模块。
出现新建工程对话框后,在工程名称编辑框输入合适的工程名称,本例中是Ex1_01。Visual C++ 2005支持长文件名,在命名有很大的弹性。底部的编辑框是解决方案名称,默认时解决方案文件夹名称和工程名称一样。需要时可以修改解决方案名称。在中间的Location编辑框是工程文件夹存储路径,可以按需修改。如果只是输入了工程名称,解决方案工程文件夹名称会被自动的设置为工程名称。如果解决方案文件夹不存在它就会被创建。可以通过Location编辑框输入不同的路径,或者是Browse按钮进行选择。点击OK后会显示图1-7所示Win32应用程序向导。
此向导对话框说明了当前的工程设置。点击Finish按钮后向导自动根据设置创建相应的工程文件。点击向导对话框左边的Application Settings会显示图1-8所示的应用程序设置页。
图1-7
图1-8
在应用程序设置页可以设置工程选项。在学习C++时,通常创建的工程都是选择Empty Project检验栏。此例中可以不修改这些设置直接点击Finish按钮。然后向导创建所有的默认文件。
工程文件夹的名称和工程名称是一样的。所有的工程定义文件都放在工程文件夹下。默认情况下,解决方案文件夹和工程名称一样,工程文件夹位于解决方案文件夹下。定义解决方案内容的文件也在解决方案文件夹下。在Windows浏览器中可以看到解决方案文件夹下三个文件:
· 以.sln为后缀的文件记录了此解决方案的所有工程信息
· 以.suo为后缀的文件记录了解决方案的设置选项。
· 以.ncb为后缀的文件记录了一些解决方案的智能信息。当在编辑窗口输入代码时, 智能工具提供自动完成功能和显示提示信息。
在Windows浏览器中查看工程文件夹,初始情况下有六个文件。包括一个工程内容的摘要信息文本文件ReadMe.txt。在这个ReadMe.txt中可能没有提及存储工程选项设置文件,以复合文件名称命名:Ex1_01.vcproj.ComputerName.UserName.user。
在Visual C++ 2005左边解决方案窗口会自动打开创建的工程,如图1-9所示。为了能更清晰的查看解决方案切换页的名称,图中增加了每个切换页的宽度。
图1-9
解决方案页显示了解决方案下的所有工程和包含的文件,此例中只有一个工程。双击解决方案的文件名就会在右边的编辑窗口附加一页显示文件的内容。在右边的多页编辑窗口中可以及时的交替显示,只需简单的单击相应的切换按钮。
类视图页显示工程定义的类,包括每个类的内容。在本例中没有类,因此视图是空的。在后面讨论类的时候,通过类视图可以很方便、快速的访问程序中定义的每个类定义、实现以及相互转移代码。
属性管理页显示了工程的Debug、Release属性设置。在本章后面会介绍这些版本信息。在显示的属性上点击右键,通过弹出菜单选择、修改属性。此时会显示修改属性的对话框。任何时候按下Alt+F7都会显示属性框。在讨论程序的Debug、Release版时会介绍更多信息。
资源视图页包含对话框、图标、菜单、工具栏和其他程序使用的资源。本例中是控制台程序,没有使用资源。在编写窗口程序时,会涉及更多的资源。在资源视图页可以编辑、添加工程的可用资源。
和Visual C++ 2005IDE的大多工具一样,在解决方案浏览窗口和其他切换页上或者一些空白区点击右键,也有上下文相关的弹出菜单。如果解决方案浏览窗口影响了编码位置,可以点击自动隐藏按钮。需要显示时再点击IDE窗口左边的名字页。
编辑源代码
应用程序向导会生成可编译、执行的完整Win32控制台程序。只是这个程序没有任何实际的功能,为了让程序有意义需要修改代码。如果代码文件在编辑窗口不可见,在解决方案浏览窗口中双击Ex1_01.cpp文件。此文件是应用程序向导生成的主程序文件。打开后的效果如图1-10。
图1-10
如果图中的代码行号没有显示,从主菜单的Tools -> Options,可以显示选项设置对话框。展开左边Text Editor下的C/C++树子项,选择General。然后选中对话框右边的Line Numbers检测栏。下面会简单介绍图1-10中代码的功能,详细的信息后面讲解。
程序开始的两行是注释,所有在“//”后此行的字符都被编译器忽略。当你想添加注释时,只需要在注释前加上“//”。
第四行是#include指令,通过#include指令把stdafx.h文件的内容加入到文件此位置。这是在C++程序中把.h头文件添加到.cpp源文件的标准方法。
_tmain()函数开始第一行也是此源代码文件的第一行可执行文件。C++程序的函数就是一个简单的可执行命名程序单元。每个C++程序至少由一个函数组成,通常是多个函数。
文件的第八、第十行的左右括号分别把_tmain()函数的所有可执行代码封装起来。真正的可执行代码只是第十行,它的作用是结束程序。
现在可以添加如下的两行代码到代码编辑窗口:
// Ex1_01.cpp :定义控制台程序的入口点
#include “stdafx.h”
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
std::cout << “Hello world!\n”;
return 0;
}
没有阴影的代码是自动生成的,阴影下的代码需要自己添加。为了产生新的空白行,可以把鼠标放在前一行文本的末尾按下回车键,然后就可以输入代码。请确保程序和前面的例子代码一样,否则可能有编译错误。
第一行输入代码是#include指令,把ISO/ANSI C++的标准头文件内容加入到这个源文件中。<iostream>定义了基础的I/O操作工具,以及在第二个附加中使用的把内容输出到命令行。std::cout是标准输出流,在第二个附加语句中把字符串“Hello world!\n”写入std::cout。在双引号之间的字符串会写入命令行然后显示出来。
编译解决方案
编译解决方案按下F7或者Build->Build Solution菜单项。同样可以点击工具栏上相应的按钮。与Build菜单一样功能的工具栏可能没有显示,想要显示直接在工具栏区点击右键从弹出菜单选择Build工具栏。例子程序应该可以编译成功。如果有错误,请检测在你输入两行额外代码时是否有误。仔细检查这两行代码。
编译控制台程序的输出文件
例子程序编译无错后,在Windows浏览器中查看工程文件夹,有一个新的子文件夹Debug。此文件夹包含刚才的编译操作所输出的文件。在Debug文件夹下有多个不同的文件。
除了程序的可执行文件.exe,对其他的文件可以不作详细的了解。如果你对这些文件好奇,下面会简单快速的说明这些文件信息。
文件扩展名
|
描述信息
|
.exe
|
程序的可执行文件,只有在编译、链接都成功后才会产生。
|
.obj
|
对象文件,是编译器根据源代码产生的机器码。链接器需要这些文件,它们和函数库一起产生EXE文件。
|
.ilk
|
重新编译工程的时候链接器使用的文件。使连接器只把修改过的源代码对象文件逐步的链接到已经存在的EXE中。可以避免在修改程序时每次都重新链接所有的代码。
|
.pch
|
预编译头文件。通过预编译头文件,可以把大量很少修改的主题代码(特别是C++程序库代码)预先处理一次存入.pch文件。通过.PCH文件充分的减少代码重新编译的时间。
|
.pdb
|
包含在DEBUG模式下运行程序需要的DEBUG信息。在DEBUG下,可以动态检测程序运行过程中生成的信息。
|
.idb
|
包含重新编译解决方案时需要的信息。
|
程序的Debug和Release版本
在菜单Project -> Ex1_01 Properties下,可以设置工程的很多属性。可以设置源代码在编译、链接过程中的处理方式。所有这些设置都统称为配置,它们影响最后生成的程序版本。创建新的工程工作区时,Visual C++ 2005自动为创建程序两个不同的配置版本:一是DEBUG版,包含有帮助调试程序的信息。在DEBUG版,程序发生错误时,可以逐句执行语句来检测程序的数据。另一个是RELEASE版,不包含调试信息,含有代码优化设置。编译器通过代码优化可以生成最高效的可执行模块。这两个版本的配置信息足够满足本书的学习。如果想加入其他的程序配置,可以通过Build -> Configuration Manager菜单访问配置。如果没有加载任何工程,这个菜单项不会存在。虽然这不是什么大问题,但是在你浏览菜单寻找该项时可能会有迷惑。
在如图1-1所示的配置管理对话框中,可以从Active solution configuration的下拉列表选择程序工作的配置文件版本。
图1-11
从列表选择了程序的配置版本后用Close按钮关闭对话框。在开发程序时,通常使用Debug版。在DEBUG下完全调试正确后,通常会再选择Release重新编译。Release下产生的代码是经过优化,没有调试和跟踪信息,因此重新运行速度更快,占用的内存更少。
执行程序
成功编译解决方案后,用Ctrl+F5执行程序,你会看到图1-12一样的执行结果。
图1-12
如你所见,窗口中输出了双引号直接的字符内容。字符串最后的“\n”是特殊字符系列,称为转义字符,表示换行符号。转义字符的作用是再字符串中表示一些特殊的不能用键盘直接输入的字符。
实例 —— 创建空的控制台工程
先前的例子工程包含一些对C++简单程序来说不需要的额外数据。默认选中的预编译头会使工程预编译stdafx.h文件的内容。此选项对含有大量代码的C++程序可以减少处理时间,但是对我们的例子没有什么用处。在下面的实例中,创建空工程然后自己添加源代码。将用一个新的Win32控制台程序解决方案(Ex1_02)来说明创建过程。在新建工程对话框里输入工程名称后点击OK按钮,在新的Win32应用程序向导对话框左边点击Application Settings。在Additional options中选中Empty project检测框。如图1-13所示。
图1-13
点击Finish按钮后,会创建和前面一样的工程,只是这次的工程中没有任何文件。下面向工程添加新的源代码文件。右键点击解决方案窗口,选择弹出菜单的Add -> New Item。在Add New Item对话框左边选择Code,然后再从右边选择C++ File(.CPP)。最后输入文件名Ex1-02。如图1-14所示。
图1-14
点击Add按钮后,新文件会加入到工程中,同时在编辑器窗口显示。当然,现在的文件是空的,在其中输入下面的代码:
// Ex1_02.cpp 一个简单的控制台程序
#include <iostream> //基本的输入、输出库
int main()
{
std::cout << “This is a simple program that outputs some text.” << std::endl;
std::cout << “You can output more lines of text” << std::endl;
std::cout << “just by repeating the output statement like this.” << std::endl;
return 0; // 返回到操作系统
}
在输入代码时,窗口会自动缩进对齐,C++用缩进对齐来改善代码的可读性。在回车的时候,编辑器根据前一行代码自动进行缩进对齐。输入时也可以看到语法颜色高亮。根据输入内容的不同,编辑器会自动分配一个颜色给不同的元素,据此显示不同的颜色。
上面的代码是一个完整的程序。与前一个应用程序向导生成的例子有两个不同之处。一是没有包含stdafx.h文件。此次不使用它是因为程序中没有使用预编译头工具。二是函数名称是main,而不是_tmain。实际上所有的ISO/ANSI C++程序都是从main()开始执行的。微软同时也提供了另一个名为wmain的函数,根据程序是否使用unicode字符,_tmain可以表示main()或者wmain。在前面的例子中,_tmain在内部被定义为main。在所有的ISO/ANSI C++选择中都使用名称main。
输出语句有一点不同,在main()的第一个语句是:
std::cout << “This is a simple program that outputs some text.” << std::endl;
语句中有两个“<<”操作符。每个的作用都是把后续的字符串传送到std::cout显示。std::cout是标准输出流。第一个在双引号之间的字符串被送到输出流,第二个的std::endl是标准程序库中定义的特殊字符,表示换行。前面也使用过字符串末尾的转义字符‘\n’来产生新行。所以上面的语句也可以写为:
std::cout << “This is a simple program that outputs some text.\n”;
为什么这行代码用阴影表示,而上一行没有?因为上一行代码是为了方便解释而重复出现的。此行代码在之前没有出现过,是新的写法。所以加了阴影。
现在可以和前面的例子一样编译工程。编译时如果编辑窗口的代码文件没有保存,会自动保存。编译成功后,用Ctrl+F5执行出现。效果如图1-15所示。
图1-15
错误处理
如果输入的程序不正确,当然会有错误发生。为了进行测试,可以故意在程序中引入错误。对已经有错误的程序可以直接用来测试。在本例的源代码编辑窗口中删除倒数第二行(第8行)末尾的分号。再编译源代码,应用出现底部的输出窗口会显示下面的错误信息:
C2143: syntax error : missing ‘;’ before ‘return’
编译时的每个错误都有一个错误号,通过它可以在文档中查找解决方法。现在的错误原因很明显。但是大多数时候,需要查找文档来找到问题的原因。为了得到文档中关于此错误的信息,可以在输出窗口中对应的输出行上按下F1键,会自动打开一个新的窗口来显示相应的错误有关信息。你可以就用上面的C2143错误试试按下F1看效果。
修改错误后,重新编译工程。重新编译的速度会快很多,因为工程定义会自动跟踪组成工程的每个文件的变化情况。进行普通编译时,Visual C++ 2005自动和最近的上一次编译做比较,只编译那些已经修改过的文件。这就意味着如果工程有多个文件,在一次编译完成后只修改了其中的一个文件,在链接创建新的EXE文件前只有那个修改过的文件才会编译。
除了Win32控制台程序外,还有CLR控制台程序。下一节将介绍CLR控制台程序。
实例——创建CLR控制台工程
按下Ctrl+Shift+N键打开New Project对话框。选择CLR类型和CLR Console Application程序模板。如图1-16所示。
图1-16
输入名称Ex1_03再点击OK按钮,应用程序向导自动创建工程的文件。CLR控制台程序没有其他的设置选项。所以此模板的CLR控制台程序初始文件都是一样的。如果你想建立空的工程(虽然对本书的学习没有多大的作用)有单独的空的CLR工程模板。
从图1-17的解决方案浏览器窗口可以看到,与Win32控制台工程相比有一些其他的文件。
在虚拟资源文件夹下有两个文件。.ico文件存储应用程序图标,在程序最小化的时候显示。.rc文件记录了应用程序使用的资源文件——此例中只是有一个图标。
图1-17
工程中有一个名为AssemblyInfo.cpp的文件。每个CLR程序都有一个或多个程序集,程序集是形成函数单元的代码和资源集合。程序集也包含一些CLR的扩展数据;其中有使用数据的类型说明;代码的版本信息;其他程序集能否访问此集合的权限信息。简言之,一个程序集就是CLR程序所有的基础编译模块。
如果编辑窗口中没有显示Ex1_03.cpp源代码文件,在解决方案浏览器窗口双击文件,编辑窗口会如图1-18所示。
图1-18
从效率上考虑,CLR程序使用预编译头来提供效率。所以和本地C++控制台程序一样,CLR程序默认也有#include指令。下一行代码是:
using namespace System;
所有的.Net工具函数库都是定义在namespace空间中的。所有可能用到的标准类函数都是在名字空间System内。此行代码表示此后程序代码都是使用System名字空间。到底声明是名字空间呢?
名字空间是一个非常简单的概念。程序中的代码、形成.Net库的代码都会有大量需要命名的东西——数据类型、变量、函数代码块都需要命名。问题就是碰巧你使用的命名已经在库中使用了,这就会引起名称混乱。名字空间提供了解决这个问题的办法。所有定义在名字空间System内的函数库代码名字都有一个隐含的名字前缀,这个前缀名就是名字空间的名称。因此如果库中名字为String,它的实际名字是System::String。因此如果你在代码中不注意使用到了String,那么就应该用System::String来访问.Net库中的String。
两个冒号[域]是范围解析操作符。此处范围解析操作符把名字空间名称System和类型名称String分隔开来。在前面的本地C++程序中也有过范围解析操作符std::cout和std::endl。它们具有同样的功能:std是本地C++程序库的名字空间,cout和endl是在std名字空间类定义的,分别代表标准输出流和换行字符。
事实上,例子中通过using namespace语句,可以使用System名字空间内的任何名称,而不需加上空间的名称前缀。如果你遇到了自定义名称和库中的名称冲突,解决方法就是可以移除using namespace语句,给库的名称加上明确的名字空间名称限定。在第二章会讲述更多名字空间的知识。
按下Ctrl+F5编译、执行程序。输出效果如图1-19。
图1-19
输出结果和第一个例子一样。输出是由下面的语句产生的。
Console::WriteLine(L”Hello World”);
此句使用了一个.Net库函数,把双引号之间的字符串写入命令行。因此CLR和Ex1_01中的本地C++程序语句的等价的:
std::cout << “Hello world!\n”;
CLR语句比本地C++语句有更直接的外观效果。
Visual C++ 2005的设置选项
Visual C++ 2005中有两种设置:一种是设置Visual C++ 2005提供的工具,它对每个工程都有效。另一种是每个工程的单独设置,它可以改变工程代码在编译、链接时的处理方式。从主菜单选择Tools -> Options可以打开选项设置对话框。对话框的效果如图1-20所示。
图1-20
点击左边的子窗口中每个项目前的加号,打开子项列表。图1-20打开了Project and Solutions下的General子项。在对话框右边显示出左边相关主题的设置。也许现在你只关心部分的设置项,但是还是建议你浏览所有的设置内容,对它有一个整体的了解。点击标题栏的帮助按钮(问号按钮)会显示当前设置项的解释信息。
也许你需要改变创建工程的默认路径,修改图1-20中第一个Environment的设置项,改变projects和solutions的存储路径。
在左边的Projects and Solutions -> VC++ Project Settings下的设置项,是对所有的工程都有效的。从菜单Project -> Properties可以修改指定工程的设置。这个菜单项的名字中可以看出当前工程的名字。
创建、执行Windows应用程序
前面的工程是不是都很容易。现在开始创建两个Windows应用程序。先用MFC创建本地的C++应用程序。然后创建CLR下的Windows Forms应用程序。对这两个生成的程序,不会全部详细讨论它们的工程文件内容。只是在某些细节方面,才介绍一些相关知识来帮助我们理解程序。通过这种方法来帮助理解程序执行过程。
创建MFC应用程序
开始创建工程的时候,如果已经有一个活动工程(Visual C++ 2005的主窗口会显示工程名称),可以在File -> Close Solution关闭解决方案。如果没有直接关闭,创建工程时也会自动关闭当前的解决方案。
用菜单New -> Project(或者Ctrl+Shift+N)打开New Project对话框。Project Type选择MFC,工程模板选择MFC Application。如图1-21一样输入Ex1_04的工程名称。
图 1-21
点击OK按钮后,进入到应用程序向导对话框。在此对话框中可以设置很多应用程序包含的选项。都可以在对话框右边的选项列表进行判断。如图1-22。后面会介绍一些具体的选项。
本例中可以忽略这些设置,接受默认值,点击Finish按钮用默认设置创建工程。之后的解决方案浏览器窗口如图1-23所示。
图 1-22
图1-23
图1-23中已经通过Property Manager的右键菜单Hide隐藏了Property Manager。向导创建了很多的文件。编写窗口程序时,需要大量的时间努力学习相关知识。其中的.CPP文件包含可执行的源代码。.H文件包含可执行代码需要的定义信息。.ICO是图标文件。通过子文件夹分类,可以进行快速的访问。它们都是虚拟的文件夹。实际的工程文件夹下不会存在。
在Windows浏览器中查看解决方案文件夹,或者其他可以看到文件的方法,你会发现有24个文件。3个在解决方案文件夹下,另外17个文件在工程文件夹下,4个在工程文件夹下的res文件夹中。res子文件夹包含程序使用的资源文件,如菜单图标等。我们只是在输入一个工程名称后就产生了如此多的文件。正是因为产生的文件很多,为每个工程建立单独的目录就很有必要了。
工程中的ReadMe.txt文件中解释了MFC应用程序向导生成的每个文件的作用。需要时可以用Notepad、WordPad或者Visual C++ 2005的编辑器查看其内容。在解决方案中双击文件就可以在编辑窗口中打开。
编译、执行MFC应用程序
执行程序前,必须编译工程——编译源代码链接模块,与控制台程序一样。可以用Ctrl+F5编译然后立即执行。一个单独的键盘快捷键完成两项工作,节约时间。
编译后,输出窗口显示没有错误,程序开始执行。执行效果如图1-24所示。
图1-24
程序的功能非常完整,有菜单、工具栏。尽管程序没有特殊的功能(这些功能需要自己添加)。但是所有的菜单都实现了。你还可以从File -> New创建新的子窗口。
利用应用程序向导创建Windows程序非常容易。当我们不需要Ex1_04这样简单的程序时,就需要把程序的外衣一层一层的剥去,深入分析内部结构,实现更丰富的功能就不是很难了。当然,有些人愿意花上一两个月的准备时间,然后抛弃Visual C++ 2005的辅助工具,用老的编程习惯来编写Windows程序。这就是为什么一些程序员过去常常吃寿司。随着Visual C++ 2005的到来,那样的情景已经不复存在。但是你将不可能知道编程技术角有什么?如果你喜欢寿司,最好给自己选择一个正确的方向。
创建Windows Forms应用程序
Windows Forms应用程序采用不同的应用程序向导。创建一个新的工程,选择CLR Project types下的Windows Forms Applicaion模板。输入Ex1_05工程名,如图1-25。
图 1-25
此类程序没有其他设置,直接点击OK按钮创建工程。解决方案浏览器窗口显示了自动生成的文件,如图1-26。
图1-26
在工程的目录下,此工程只有相当少的文件。包括解决方案文件总共只有15个。因此这类工程的初始GUI比使用MFC的本地C++程序更简单。Windows Forms应用程序没有菜单和工具栏。只有一个窗口。当然,可以添加菜单和工具栏,Windows Forms应用程序向导默认你不需要菜单和工具栏。编辑窗口也有些不同,如图1-27。
图1-27
编辑窗口显示了应用程序窗口的图形而不是代码。因为开发Windows Forms程序的GUI是面向图形设计而不是编码设计。可以同画图一样拖放GUI组件到应用程序窗口。Visual C++ 2005会自动生成显示代码。按下Ctrl+Alt+X,或者菜单View -> Toolbox,将看到一个额外显示GUI组件列表的窗口,如图1-28。
图1-28
窗口Toolbox 显示了可以添加到Windows Forms应用程序的标准组件列表。可以尝试给Ex1_05添加按钮:点击Toolbox列表的Button,然后在编辑窗口中Ex1_05的客户区想显示按钮的位置进行点击。拖动按钮的边界可以改变其大小。拖动按钮改变其位置。同样可以修改按钮标题:从键盘输入Start然后按下回车。标题改变了同时激活、打开了另一个窗口:显示按钮所有的属性。关于属性不会再进行介绍,只是需要记住它们都是影响按钮外观效果的规范说明。修改这些属性以满足程序的需要。再添加一个Stop标题的按钮。如图1-29。
图1-29
可以再任何时候编辑GUI组件。相应的代码会自动调整。可以采用同样的方法添加其他的组件。然后用Ctrl+F5编译、执行程序。很简单,对吧!
总结
本章包含了用Visual C++ 2005创建各种应用出现的基本方法。利用应用出现向导,创建、执行本地、CLR控制台程序。创建MFC窗口程序和基于CLR的Windows Forms程序。
本章的主要知识点有:
· 通用语言运行时(CLR)是微软实现的一个通用语言规范(CLI)标准。
· .Net框架由CLR和.Net库组成。.Net库提供了基于CLR的应用程序函数支持。
· 本地C++应用程序是以支持ISO/ANSI C++语言的。
· 用C++/CLI编写的应用程序需要CLR一起执行。
· 解决方案是一种工程容器。由一个或多个工程组合起来解决某类信息处理问题。
· 工程是代码和资源容器,代码和资源也是构成程序单元函数的元素。
· 程序集是CLR程序的基本单元。所有的CLR出现都是由一个或多个程序集组成。
从下一章开始,本书前半部分会大量运用控制台程序。所有说明C++语言要素的例子都是Win32、CLR控制台程序。在结束对C++语言的学习后才会再次回到基于MFC的应用程序向导上。