- 在线时间
- 0 小时
- 最后登录
- 2007-9-23
- 注册时间
- 2004-9-10
- 听众数
- 3
- 收听数
- 0
- 能力
- 0 分
- 体力
- 9975 点
- 威望
- 7 点
- 阅读权限
- 150
- 积分
- 4048
- 相册
- 0
- 日志
- 0
- 记录
- 0
- 帖子
- 1893
- 主题
- 823
- 精华
- 2
- 分享
- 0
- 好友
- 0

我的地盘我做主
该用户从未签到
|
<b><FONT face=宋体 size=6> </FONT></b>< align=center>工程框架分析</P><FONT face=宋体 size=3>< align=justify>在上一讲中,我们创建了一个</FONT><FONT face="宋体, MS Song" size=3>MP3Collect</FONT><FONT face=宋体 size=3>工程,并学习了怎样用工程设置对话框来设置工程的各种属性。本讲我们将要进一步深入到工程的内部去了解其结构。</P><UL><B>< align=justify><LI>工程的文件组成 & q9 K2 i, |! y; |/ I
</LI></UL></B>< align=justify>第五讲曾经提到,新创建的工程</FONT><FONT face="宋体, MS Song" size=3>MP3Collect</FONT><FONT face=宋体 size=3>在工作目录下有一系列文件,它们分别是:</P>< align=justify>工程文件:</FONT><FONT size=3><FONT face="宋体, MS Song">MP3Collect.bpr</FONT></P></FONT><FONT face=宋体 size=3>< align=justify>单元文件:</FONT><FONT face="宋体, MS Song" size=3>MP3Collect.cpp</FONT><FONT face=宋体 size=3>、</FONT><FONT face="宋体, MS Song" size=3>MainForm.cpp</FONT><FONT face=宋体 size=3>及其头文件</FONT><FONT size=3><FONT face="宋体, MS Song">MainForm.h</FONT></P></FONT><FONT face=宋体 size=3>< align=justify>窗体文件:</FONT><FONT face="宋体, MS Song" size=3>MainForm.dfm</FONT><FONT face=宋体 size=3>。</P>< align=justify>资源文件:</FONT><FONT size=3><FONT face="宋体, MS Song">MP3Collect.res</FONT></P></FONT><FONT face=宋体 size=3>< align=justify>这些文件的有机组合构成了工程。下面心铃将逐一介绍各个文件的格式和内容。</P><UL><B>< align=justify><LI>工程文件——</FONT><FONT size=3><FONT face="宋体, MS Song">MP3Collect.bpr </FONT><p></LI></UL></B>< align=justify>MP3Collect.bpr</FONT><FONT face=宋体 size=3>是工程的</FONT><FONT size=3>Makefile</FONT><FONT face=宋体 size=3>文件,是一个文本文件,它以</FONT><FONT size=3>XML</FONT><FONT face=宋体 size=3>标记语言的格式描述了工程的编译连接选项等各项设置。通常情况都不要手工修改此文件,而是通过工程设置对话框来修改。</P><UL><B>< align=justify><LI>应用程序入口单元——</FONT><FONT size=3><FONT face="宋体, MS Song">MP3Collect.cpp </FONT><p></LI></UL></B>< align=justify>MP3Collect.cpp</FONT><FONT face=宋体 size=3>文件中包含了</FONT><FONT size=3>Windows</FONT><FONT face=宋体 size=3>应用程序的入口</FONT><FONT size=3>WinMain()</FONT><FONT face=宋体 size=3>函数,同时指明了应用程序包含的其它源程序文件。下面我们来逐行分析</FONT><FONT size=3>MP3Collect.cpp</FONT><FONT face=宋体 size=3>的源代码(为了方便说明,心铃在每一行代码前都添加了行号,实际的代码中并没有这些行号):</P></FONT><FONT face="Courier New" size=3>< align=justify>1</FONT><FONT face=宋体 size=3>.</FONT><FONT face="Courier New" size=3>#include <vcl.h></P>< align=justify>2</FONT><FONT face=宋体 size=3>.</FONT><FONT face="Courier New" size=3>#pragma hdrstop</P>< align=justify>3</FONT><FONT face=宋体 size=3>.</FONT><FONT face="Courier New" size=3>USERES("MP3Collect.res");</P>< align=justify>4</FONT><FONT face=宋体 size=3>.</FONT><FONT face="Courier New" size=3>USEFORM("MainFrom.cpp", MainForm);</P>< align=justify>5</FONT><FONT face=宋体 size=3>.</FONT><FONT face="Courier New" size=3>WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)</P>< align=justify>6</FONT><FONT face=宋体 size=3>.{</P></FONT><FONT face="Courier New" size=3>< align=justify>7</FONT><FONT face=宋体 size=3>. </FONT><FONT face="Courier New" size=3>try</P>< align=justify>8</FONT><FONT face=宋体 size=3>. {</P></FONT><FONT face="Courier New" size=3>< align=justify>9</FONT><FONT face=宋体 size=3>. </FONT><FONT face="Courier New" size=3>Application->Initialize();</P>< align=justify>10</FONT><FONT face=宋体 size=3>. </FONT><FONT face="Courier New" size=3>Application->CreateForm(__classid(TMainForm),&MainForm);</P>< align=justify>11</FONT><FONT face=宋体 size=3>. </FONT><FONT face="Courier New" size=3>Application->Run();</P>< align=justify>12</FONT><FONT face=宋体 size=3>. }</P></FONT><FONT face="Courier New" size=3>< align=justify>13</FONT><FONT face=宋体 size=3>. </FONT><FONT face="Courier New" size=3>catch (Exception &exception) </P>< align=justify>14</FONT><FONT face=宋体 size=3>. { </P></FONT><FONT face="Courier New" size=3>< align=justify>15</FONT><FONT face=宋体 size=3>. </FONT><FONT face="Courier New" size=3>Application->ShowException(&exception);</P>< align=justify>16</FONT><FONT face=宋体 size=3>. }</P></FONT><FONT face="Courier New" size=3>< align=justify>17</FONT><FONT face=宋体 size=3>. </FONT><FONT face="Courier New" size=3>return 0;</P><P align=justify>18</FONT><FONT face=宋体 size=3>.}</P><P align=justify>第</FONT><FONT face="宋体, MS Song" size=3>1</FONT><FONT face=宋体 size=3>行是一条预处理指令。</FONT><FONT face="宋体, MS Song" size=3>CBuilder</FONT><FONT face=宋体 size=3>编译器在正式编译一段代码之前,会预先扫描一遍代码,并根据预处理指令进行一些预先的处理,</FONT><FONT face="宋体, MS Song" size=3>CBuilder</FONT><FONT face=宋体 size=3>编译器一共支持十几个预处理指令,每条预处理指令前都有一个“</FONT><FONT face="宋体, MS Song" size=3>#</FONT><FONT face=宋体 size=3>”符号。“</FONT><FONT face="宋体, MS Song" size=3>#include </FONT><FONT face=宋体 size=3>……”指令的意义是包含一个头文件,这在里就是告诉预处理器将</FONT><FONT face="宋体, MS Song" size=3>vcl.h</FONT><FONT face=宋体 size=3>包含进来。</FONT><FONT face="宋体, MS Song" size=3>vcl.h</FONT><FONT face=宋体 size=3>是使用</FONT><FONT face="宋体, MS Song" size=3>VCL</FONT><FONT face=宋体 size=3>库时必需的头文件,其中包括了使用</FONT><FONT face="宋体, MS Song" size=3>VCL</FONT><FONT face=宋体 size=3>库所需的各种声明和定义。</FONT><FONT face="宋体, MS Song" size=3>vcl.h</FONT><FONT face=宋体 size=3>内部又包含了多个其它的头文件,因此编译这个头文件需要花费较长的时间,为了缩短编译时间,</FONT><FONT face="宋体, MS Song" size=3>CBuilder</FONT><FONT face=宋体 size=3>对这种些固定的头文件采取了预编译处理,第一次编译时进行完全编译,在以后的编译过程中,只要这些头文件没有变化,就不再处理它们,</FONT><FONT face="宋体, MS Song" size=3>MP3Collect.cpp</FONT><FONT face=宋体 size=3>中的第二条语句就是</FONT><FONT face="宋体, MS Song" size=3>CBuilder</FONT><FONT face=宋体 size=3>的预编译开关指令,它表示预编译头文件部分到此结束。</P><P align=justify>第</FONT><FONT face="宋体, MS Song" size=3>3</FONT><FONT face=宋体 size=3>、</FONT><FONT face="宋体, MS Song" size=3>4</FONT><FONT face=宋体 size=3>行的</FONT><FONT face="宋体, MS Song" size=3>USERES</FONT><FONT face=宋体 size=3>和</FONT><FONT face="宋体, MS Song" size=3>USEFORMS</FONT><FONT face=宋体 size=3>均为</FONT><FONT face="宋体, MS Song" size=3>CBuilder</FONT><FONT face=宋体 size=3>定义的宏,前者用来定义工程的资源文件,后者用来指明工程中包含的窗体。</FONT><FONT face="宋体, MS Song" size=3>USEFORMS</FONT><FONT face=宋体 size=3>的第一个参数为窗体的单元文件名,第二个参数为窗体对象的名称。如果工程中有多个窗体,会在这里逐一用</FONT><FONT face="宋体, MS Song" size=3>USEFORMS</FONT><FONT face=宋体 size=3>宏指明。</P><P align=justify>从第</FONT><FONT face="宋体, MS Song" size=3>5</FONT><FONT face=宋体 size=3>行到第</FONT><FONT face="宋体, MS Song" size=3>18</FONT><FONT face=宋体 size=3>行定义了函数</FONT><FONT face="宋体, MS Song" size=3>WinMain</FONT><FONT face=宋体 size=3>,这是</FONT><FONT face="宋体, MS Song" size=3>Windows</FONT><FONT face=宋体 size=3>应用程序的标准入口函数,其参数的含义如下:</FONT><FONT face="宋体, MS Song" size=3>HINSTANCE hInstance</FONT><FONT face=宋体 size=3>(程序的当前实例句柄),</FONT><FONT face="宋体, MS Song" size=3>HINSTANCE hPrevInstance</FONT><FONT face=宋体 size=3>(程序的前一个实例句柄),</FONT><FONT face="宋体, MS Song" size=3>LPSTR lpCmdLine</FONT><FONT face=宋体 size=3>,(命令行字符串指针),</FONT><FONT face="宋体, MS Song" size=3>int nCmdShow</FONT><FONT face=宋体 size=3>(主窗口的显示方式)。</P></FONT><FONT size=3><P align=justify>WinMain</FONT><FONT face=宋体 size=3>函数的主体是</FONT><FONT size=3>try</FONT><FONT face=宋体 size=3>语句引出的一段代码和</FONT><FONT size=3>catch</FONT><FONT face=宋体 size=3>语句引出的异常处理代码。</FONT><FONT size=3>try</FONT><FONT face=宋体 size=3>和</FONT><FONT size=3>catch</FONT><FONT face=宋体 size=3>是</FONT><FONT size=3>C++</FONT><FONT face=宋体 size=3>中的关键字,用来处理程序运行时产生的异常,关于</FONT><FONT size=3>CBuilder</FONT><FONT face=宋体 size=3>的异常处理机制,讲座后期还要详细介绍,这里大家需要了解的只是:</FONT><FONT size=3>try</FONT><FONT face=宋体 size=3>语句引出一段可能产生异常的代码,如果运行时该段代码产生了异常,则中断该代码的执行,自动转入到由</FONT><FONT size=3>catch</FONT><FONT face=宋体 size=3>引出的异常处理代码中运行,一条</FONT><FONT size=3>try</FONT><FONT face=宋体 size=3>语句至少要有一条</FONT><FONT size=3>catch</FONT><FONT face=宋体 size=3>语句与之相对应,如果不产生异常,</FONT><FONT size=3>catch</FONT><FONT face=宋体 size=3>中的异常处理代码不会被执行。</P><P align=justify>下面我们来分析</FONT><FONT face="宋体, MS Song" size=3>try</FONT><FONT face=宋体 size=3>语句所包括的第</FONT><FONT face="宋体, MS Song" size=3>9</FONT><FONT face=宋体 size=3>、</FONT><FONT face="宋体, MS Song" size=3>10</FONT><FONT face=宋体 size=3>、</FONT><FONT face="宋体, MS Song" size=3>11</FONT><FONT face=宋体 size=3>行代码,它们都引用了</FONT><FONT face="宋体, MS Song" size=3>Application</FONT><FONT face=宋体 size=3>对象。</FONT><FONT face="宋体, MS Song" size=3>Application</FONT><FONT face=宋体 size=3>对象代表</FONT><FONT face="宋体, MS Song" size=3>Windows</FONT><FONT face=宋体 size=3>应用程序自身(在这里就是</FONT><FONT face="宋体, MS Song" size=3>MP3Collect</FONT><FONT face=宋体 size=3>),它对应的</FONT><FONT face="宋体, MS Song" size=3>VCL</FONT><FONT face=宋体 size=3>类是</FONT><FONT face="宋体, MS Song" size=3>TApplication</FONT><FONT face=宋体 size=3>,该类实现了应用程序初始化、创建窗体、运行、消息循环、异常处理、退出等基本功能。</FONT><FONT face="宋体, MS Song" size=3>Application</FONT><FONT face=宋体 size=3>对象的定义和创建是在</FONT><FONT face="宋体, MS Song" size=3>VCL</FONT><FONT face=宋体 size=3>库中完成的,它的声明</FONT><FONT face="宋体, MS Song" size=3>extern TApplication * Application</FONT><FONT face=宋体 size=3>位于头文件</FONT><FONT face="宋体, MS Song" size=3>Forms.hpp</FONT><FONT face=宋体 size=3>中(</FONT><FONT face="宋体, MS Song" size=3>vcl.h</FONT><FONT face=宋体 size=3>包含了</FONT><FONT face="宋体, MS Song" size=3>Forms.hpp</FONT><FONT face=宋体 size=3>)。第</FONT><FONT face="宋体, MS Song" size=3>9</FONT><FONT face=宋体 size=3>行语句调用</FONT><FONT face="宋体, MS Song" size=3>Application</FONT><FONT face=宋体 size=3>对象的</FONT><FONT face="宋体, MS Song" size=3>Initialize</FONT><FONT face=宋体 size=3>方法来初始化应用程序。第</FONT><FONT face="宋体, MS Song" size=3>10</FONT><FONT face=宋体 size=3>行语句创建主窗体,</FONT><FONT face="宋体, MS Song" size=3>CreateForm</FONT><FONT face=宋体 size=3>函数的第一个参数为主窗体类,第二个参数为主窗体对象,</FONT><FONT face="宋体, MS Song" size=3>__classid</FONT><FONT face=宋体 size=3>是获取</FONT><FONT face="宋体, MS Song" size=3>VCL</FONT><FONT face=宋体 size=3>类的操作符。如果应用程序中有多个自动创建的窗体,都会在这里以同样的方式创建,其中第一个创建的窗体为主窗体。第</FONT><FONT face="宋体, MS Song" size=3>11</FONT><FONT face=宋体 size=3>行语句调用</FONT><FONT face="宋体, MS Song" size=3>Application</FONT><FONT face=宋体 size=3>对象的</FONT><FONT face="宋体, MS Song" size=3>Run</FONT><FONT face=宋体 size=3>方法开始程序的运行,</FONT><FONT face="宋体, MS Song" size=3>Run</FONT><FONT face=宋体 size=3>函数中包含了应用程序的主消息循环,只有消息循环结束后,该函数才会返回。</P><P align=justify>第</FONT><FONT face="宋体, MS Song" size=3>15</FONT><FONT face=宋体 size=3>行语句是异常处理代码,利用</FONT><FONT face="宋体, MS Song" size=3>Application</FONT><FONT face=宋体 size=3>对象的</FONT><FONT face="宋体, MS Song" size=3>ShowException</FONT><FONT face=宋体 size=3>方法显示异常事件的相关信息。第</FONT><FONT face="宋体, MS Song" size=3>18</FONT><FONT face=宋体 size=3>行语句表示应用程序结束后,返回结束代码</FONT><FONT face="宋体, MS Song" size=3>0</FONT><FONT face=宋体 size=3>。</P><UL><B><P align=justify><LI>单元文件</FONT><FONT face="宋体, MS Song" size=3>MainForm.cpp</FONT><FONT face=宋体 size=3>及其头文件</FONT><FONT size=3><FONT face="宋体, MS Song">MainForm.h </FONT><p></LI></UL></B><P align=justify>MainForm.cpp</FONT><FONT face=宋体 size=3>和</FONT><FONT size=3>MainForm.h</FONT><FONT face=宋体 size=3>一起给出了主窗体的定义,其中</FONT><FONT size=3>MainForm.h</FONT><FONT face=宋体 size=3>中定义了主窗体类</FONT><FONT size=3>TMainFrom</FONT><FONT face=宋体 size=3>。</P></FONT><FONT face="Courier New" size=3><P align=justify>1</FONT><FONT face=宋体 size=3>. </FONT><FONT face="Courier New" size=3>#ifndef MainFromH</P><P align=justify>2</FONT><FONT face=宋体 size=3>. </FONT><FONT face="Courier New" size=3>#define MainFromH</P><P align=justify>3</FONT><FONT face=宋体 size=3>. </FONT><FONT face="Courier New" size=3>#include <Classes.hpp></P><P align=justify>4</FONT><FONT face=宋体 size=3>. </FONT><FONT face="Courier New" size=3>#include <Controls.hpp></P><P align=justify>5</FONT><FONT face=宋体 size=3>. </FONT><FONT face="Courier New" size=3>#include <StdCtrls.hpp></P><P align=justify>6</FONT><FONT face=宋体 size=3>. </FONT><FONT face="Courier New" size=3>#include <Forms.hpp></P><P align=justify>7</FONT><FONT face=宋体 size=3>. </FONT><FONT face="Courier New" size=3>class TMainForm: public TForm</P><P align=justify>8</FONT><FONT face=宋体 size=3>. {</P></FONT><FONT face="Courier New" size=3><P align=justify>9</FONT><FONT face=宋体 size=3>. </FONT><FONT face="Courier New" size=3>__published: // IDE-managed Components</P><P align=justify>10</FONT><FONT face=宋体 size=3>. </FONT><FONT face="Courier New" size=3>private: // User declarations</P><P align=justify>11</FONT><FONT face=宋体 size=3>. </FONT><FONT face="Courier New" size=3>public: // User declarations</P><P align=justify>12</FONT><FONT face=宋体 size=3>. </FONT><FONT face="Courier New" size=3>__fastcall TMainForm(TComponent* Owner);</P><P align=justify>13</FONT><FONT face=宋体 size=3>.}</FONT><FONT face="Courier New" size=3>;</P><P align=justify>14</FONT><FONT face=宋体 size=3>.</FONT><FONT face="Courier New" size=3>extern PACKAGE TMainForm *MainForm;</P><P align=justify>15</FONT><FONT face=宋体 size=3>.</FONT><FONT face="Courier New" size=3>#endif</P></FONT><FONT face=宋体 size=3><P align=justify>其中第</FONT><FONT face="宋体, MS Song" size=3>1</FONT><FONT face=宋体 size=3>、</FONT><FONT face="宋体, MS Song" size=3>15</FONT><FONT face=宋体 size=3>行是条件编译指令。编译器根据这两条指令,首先检测</FONT><FONT face="宋体, MS Song" size=3>MainFormH</FONT><FONT face=宋体 size=3>是否已定义,如果未定义,才会继续编译第</FONT><FONT face="宋体, MS Song" size=3>2~14</FONT><FONT face=宋体 size=3>行的语句。第</FONT><FONT face="宋体, MS Song" size=3>2</FONT><FONT face=宋体 size=3>行定义</FONT><FONT face="宋体, MS Song" size=3>MainFormH</FONT><FONT face=宋体 size=3>,目的是避免重复编译</FONT><FONT face="宋体, MS Song" size=3>MainForm.h</FONT><FONT face=宋体 size=3>。第</FONT><FONT face="宋体, MS Song" size=3>3</FONT><FONT face=宋体 size=3>、</FONT><FONT face="宋体, MS Song" size=3>4</FONT><FONT face=宋体 size=3>、</FONT><FONT face="宋体, MS Song" size=3>5</FONT><FONT face=宋体 size=3>、</FONT><FONT face="宋体, MS Song" size=3>6</FONT><FONT face=宋体 size=3>行包含了使用窗体和控件的头文件,</FONT><FONT face="宋体, MS Song" size=3>CBuilder</FONT><FONT face=宋体 size=3>会根据窗体上的控件自动添加所需要的头文件。</P><P align=justify>第</FONT><FONT face="宋体, MS Song" size=3>7</FONT><FONT face=宋体 size=3>行是类定义的开始,其中</FONT><FONT face="宋体, MS Song" size=3>class</FONT><FONT face=宋体 size=3>是定义类的</FONT><FONT face="宋体, MS Song" size=3>C++</FONT><FONT face=宋体 size=3>关键字,</FONT><FONT face="宋体, MS Song" size=3>TMainFrom</FONT><FONT face=宋体 size=3>是类的名称,“:”符号指示类的父类,即</FONT><FONT face="宋体, MS Song" size=3>TMainFrom</FONT><FONT face=宋体 size=3>类的父类为</FONT><FONT face="宋体, MS Song" size=3>TForm</FONT><FONT face=宋体 size=3>,且继承方式为</FONT><FONT face="宋体, MS Song" size=3>public</FONT><FONT face=宋体 size=3>方式。</P><P align=justify>第</FONT><FONT face="宋体, MS Song" size=3>10</FONT><FONT face=宋体 size=3>到</FONT><FONT face="宋体, MS Song" size=3>13</FONT><FONT face=宋体 size=3>行语句为类的定义体,其中定义了类的各种属性和方法。第三讲中我们介绍过,根据外界对成员的存取限制,</FONT><FONT face="宋体, MS Song" size=3>C++</FONT><FONT face=宋体 size=3>类的成员分为</FONT><FONT face="宋体, MS Song" size=3>3</FONT><FONT face=宋体 size=3>种类型:</FONT><FONT face="宋体, MS Song" size=3>private</FONT><FONT face=宋体 size=3>私有的、</FONT><FONT face="宋体, MS Song" size=3>protect</FONT><FONT face=宋体 size=3>保护的和</FONT><FONT face="宋体, MS Song" size=3>public</FONT><FONT face=宋体 size=3>公共的,这里我们会遇到</FONT><FONT face="宋体, MS Song" size=3>CBuilder</FONT><FONT face=宋体 size=3>引入的一种新成员类型:</FONT><FONT face="宋体, MS Song" size=3>__published</FONT><FONT face=宋体 size=3>,该类型成员与</FONT><FONT face="宋体, MS Song" size=3>public</FONT><FONT face=宋体 size=3>类型成员一样可以被外界的函数访问,而不同的地方在于:</FONT><FONT face="宋体, MS Song" size=3>CBuilder</FONT><FONT face=宋体 size=3>编译连接器会为</FONT><FONT face="宋体, MS Song" size=3>__published</FONT><FONT face=宋体 size=3>类的成员生成运行时类型信息(</FONT><FONT face="宋体, MS Song" size=3>RTTI</FONT><FONT face=宋体 size=3>),使这种类型的成员能够显示在对象监视器中。对于新建的</FONT><FONT face="宋体, MS Song" size=3>TMainForm</FONT><FONT face=宋体 size=3>来说,因为还未添加任何控件和事件处理函数,所以</FONT><FONT face="宋体, MS Song" size=3>__published</FONT><FONT face=宋体 size=3>下的成员为空。如果我们在窗体上添加一个按钮,再双击该按钮添加其缺省事件处理函数:</FONT><FONT face="宋体, MS Song" size=3>Button1Click</FONT><FONT face=宋体 size=3>(),这时就会发现</FONT><FONT face="宋体, MS Song" size=3>__published</FONT><FONT face=宋体 size=3>下面多了两个成员:</P></FONT><FONT size=3><P align=justify>__published: // IDE-managed Components</P><P align=justify>TButton *Button1;</P><P align=justify>void __fastcall Button1Click(TObject *Sender);</P></FONT><FONT face=宋体 size=3><P align=justify>同样,新建的</FONT><FONT face="宋体, MS Song" size=3>TMainForm</FONT><FONT face=宋体 size=3>类中,</FONT><FONT face="宋体, MS Song" size=3>private</FONT><FONT face=宋体 size=3>类型的成员也为空。只有一个</FONT><FONT face="宋体, MS Song" size=3>public</FONT><FONT face=宋体 size=3>类型的构造函数(见第</FONT><FONT face="宋体, MS Song" size=3>12</FONT><FONT face=宋体 size=3>行)。构造函数前面的关键字“</FONT><FONT face="宋体, MS Song" size=3>__fastcall</FONT><FONT face=宋体 size=3>”是一种函数调用类型修饰符,表明该函数通过寄存器传递参数(普通的</FONT><FONT face="宋体, MS Song" size=3>C/C++</FONT><FONT face=宋体 size=3>函数是通过堆栈来传递参数),</FONT><FONT face="宋体, MS Song" size=3>CBuilder</FONT><FONT face=宋体 size=3>中窗体的成员函数都是采用</FONT><FONT face="宋体, MS Song" size=3>__fastcal</FONT><FONT face=宋体 size=3>调用类型,这样可以加快程序的运行速度。</P><P align=justify>第</FONT><FONT face="宋体, MS Song" size=3>14</FONT><FONT face=宋体 size=3>行声明了一个指向</FONT><FONT face="宋体, MS Song" size=3>TMainForm</FONT><FONT face=宋体 size=3>类对象的指针</FONT><FONT face="宋体, MS Song" size=3>MainFrom</FONT><FONT face=宋体 size=3>,根据</FONT><FONT face="宋体, MS Song" size=3>CBuilder</FONT><FONT face=宋体 size=3>编程的习惯,我们也称</FONT><FONT face="宋体, MS Song" size=3>MainFrom</FONT><FONT face=宋体 size=3>为对象。</P><P align=justify>下面我们再来看看主窗体类的实现代码,即单元文件</FONT><FONT face="宋体, MS Song" size=3>MainForm.cpp</FONT><FONT face=宋体 size=3>。</P></FONT><FONT face="Courier New" size=3><P align=justify>1</FONT><FONT face=宋体 size=3>. </FONT><FONT face="Courier New" size=3>#include <vcl.h></P><P align=justify>2</FONT><FONT face=宋体 size=3>. </FONT><FONT face="Courier New" size=3>#pragma hdrstop</P><P align=justify>3</FONT><FONT face=宋体 size=3>. </FONT><FONT face="Courier New" size=3>#include "MainForm.h"</P><P align=justify>4</FONT><FONT face=宋体 size=3>. </FONT><FONT face="Courier New" size=3>#pragma package(smart_init)</P><P align=justify>5</FONT><FONT face=宋体 size=3>. </FONT><FONT face="Courier New" size=3>#pragma resource "*.dfm"</P><P align=justify>6</FONT><FONT face=宋体 size=3>. </FONT><FONT face="Courier New" size=3>TMainForm *MainForm;</P><P align=justify>7</FONT><FONT face=宋体 size=3>. </FONT><FONT face="Courier New" size=3>__fastcall TMainForm::TMainForm(TComponent* Owner)</P><P align=justify>8</FONT><FONT face=宋体 size=3>. </FONT><FONT face="Courier New" size=3>: TForm(Owner)</P><P align=justify>9</FONT><FONT face=宋体 size=3>. {</P></FONT><FONT face="Courier New" size=3><P align=justify>10</FONT><FONT face=宋体 size=3>.}</P><P align=justify>其中第</FONT><FONT face="宋体, MS Song" size=3>1</FONT><FONT face=宋体 size=3>行与应用程序入口单元</FONT><FONT face="宋体, MS Song" size=3>MP3Collect.cpp</FONT><FONT face=宋体 size=3>一样,指示包含头文件</FONT><FONT face="宋体, MS Song" size=3>vcl.h</FONT><FONT face=宋体 size=3>。第</FONT><FONT face="宋体, MS Song" size=3>2</FONT><FONT face=宋体 size=3>行表示预编译头文件结束。第</FONT><FONT face="宋体, MS Song" size=3>3</FONT><FONT face=宋体 size=3>行包含头文件</FONT><FONT face="宋体, MS Song" size=3>MainForm.h</FONT><FONT face=宋体 size=3>。有的朋友可能已经注意到,同样是包含头文件,第</FONT><FONT face="宋体, MS Song" size=3>1</FONT><FONT face=宋体 size=3>行中用尖括号</FONT><FONT face="宋体, MS Song" size=3><></FONT><FONT face=宋体 size=3>来包括文件名,第</FONT><FONT face="宋体, MS Song" size=3>3</FONT><FONT face=宋体 size=3>行中则用引号</FONT><FONT face="宋体, MS Song" size=3>""</FONT><FONT face=宋体 size=3>来包括文件名,两者的差别是编译器在搜索头文件时查找的缺省路径有所不同,一般来说,</FONT><FONT face="宋体, MS Song" size=3>CBuilder</FONT><FONT face=宋体 size=3>的标准头文件用</FONT><FONT face="宋体, MS Song" size=3><></FONT><FONT face=宋体 size=3>来包含,而工程中的头文件则用</FONT><FONT face="宋体, MS Song" size=3>""</FONT><FONT face=宋体 size=3>来包含。</P><P align=justify>第</FONT><FONT face="宋体, MS Song" size=3>4</FONT><FONT face=宋体 size=3>行是一行预处理指令,其作用是保证单元的初始化按照单元之间的依赖过程进行。例如,“</FONT><FONT face="宋体, MS Song" size=3>UnitA</FONT><FONT face=宋体 size=3>”中使用到了“</FONT><FONT face="宋体, MS Song" size=3>UnitB</FONT><FONT face=宋体 size=3>”,则编译器应保证</FONT><FONT face="宋体, MS Song" size=3>UnitB</FONT><FONT face=宋体 size=3>应在</FONT><FONT face="宋体, MS Song" size=3>UnitA</FONT><FONT face=宋体 size=3>之前初始化。</P><P align=justify>第</FONT><FONT face="宋体, MS Song" size=3>5</FONT><FONT face=宋体 size=3>行预处理指令指明了当前的单元文件是窗体单元文件,</FONT><FONT face="宋体, MS Song" size=3>CBuilder</FONT><FONT face=宋体 size=3>集成开发环境在处理此单元文件时会自动查找同名的窗体文件(</FONT><FONT face="Courier New" size=3>*.dfm</FONT><FONT face=宋体 size=3>文件)和头文件(</FONT><FONT face="Courier New" size=3>*.h</FONT><FONT face=宋体 size=3>文件)。</P><P align=justify>第</FONT><FONT face="宋体, MS Song" size=3>6</FONT><FONT face=宋体 size=3>行定义了</FONT><FONT face="宋体, MS Song" size=3>TMainForm</FONT><FONT face=宋体 size=3>类对象</FONT><FONT face="宋体, MS Song" size=3>MainFrom</FONT><FONT face=宋体 size=3>。</FONT><FONT face="宋体, MS Song" size=3>MainForm.h</FONT><FONT face=宋体 size=3>文件中的第</FONT><FONT face="宋体, MS Song" size=3>14</FONT><FONT face=宋体 size=3>行语句与此很相似,只是多了关键词“</FONT><FONT face="宋体, MS Song" size=3>extern</FONT><FONT face=宋体 size=3>”,因为有了该关键词,使得这两句的意义完全不相同。这里的第</FONT><FONT face="宋体, MS Song" size=3>6</FONT><FONT face=宋体 size=3>行语句是定义一个变量,程序会为这个变量分配一块实实在在的内存,而</FONT><FONT face="宋体, MS Song" size=3>MainForm.h</FONT><FONT face=宋体 size=3>中的第</FONT><FONT face="宋体, MS Song" size=3>14</FONT><FONT face=宋体 size=3>行则只是声明了一个变量,声明变量的意义是告诉编译器,应用程序的某一处已经定义了这样一个变量,使得后续的代码中可以使用该变量,变量声明并不会真正分配内存,这就是声明与定义的基本区别(在有些资料中的称法可能不太相同,把变量定义称为“定义性声明”,把变量声明称为“非定义性声明”。在本讲座中,如不特殊说明,仍然使用“变量定义”和“变量声明”的称法)。</P><P align=justify>第</FONT><FONT face="宋体, MS Song" size=3>7</FONT><FONT face=宋体 size=3>到</FONT><FONT face="宋体, MS Song" size=3>10</FONT><FONT face=宋体 size=3>行语句给出了</FONT><FONT face="宋体, MS Song" size=3>TMainForm</FONT><FONT face=宋体 size=3>类的构造函数的实现。函数名前的“</FONT><FONT face="宋体, MS Song" size=3>TMainForm::</FONT><FONT face=宋体 size=3>”为作用域限制符,表示函数的作用域为</FONT><FONT face="宋体, MS Song" size=3>TMainForm</FONT><FONT face=宋体 size=3>类,即该函数为</FONT><FONT face="宋体, MS Song" size=3>TMainForm</FONT><FONT face=宋体 size=3>类的成员函数。函数的参数为</FONT><FONT face="宋体, MS Song" size=3>TComponent* Owner</FONT><FONT face=宋体 size=3>,</FONT><FONT face="宋体, MS Song" size=3>Owner</FONT><FONT face=宋体 size=3>为本窗体的父元件对象。第</FONT><FONT face="宋体, MS Song" size=3>8</FONT><FONT face=宋体 size=3>行语句表示该构造函数会首先调用其基类的构造函数,并将</FONT><FONT face="宋体, MS Song" size=3>Owner</FONT><FONT face=宋体 size=3>参数传递到基类的构造函数中。构造函数中一般进行类初始化所需要的一些操作,相应的代码可以加在第</FONT><FONT face="宋体, MS Song" size=3>9</FONT><FONT face=宋体 size=3>行和第</FONT><FONT face="宋体, MS Song" size=3>10</FONT><FONT face=宋体 size=3>行中间。</P><UL><B><P align=justify><LI>窗体文件</FONT><FONT size=3><FONT face="宋体, MS Song">MainForm.dfm </FONT><p></LI></UL></B></FONT><FONT face=宋体 size=3><P align=justify>窗体文件</FONT><FONT face="宋体, MS Song" size=3>MainForm.dfm</FONT><FONT face=宋体 size=3>为文本格式的文件,描述了窗体的各种属性及其上的元件以及元件属性,如下所示:</P><DIR></FONT><FONT size=3><P align=justify>object MainForm: TMainForm</P><P align=justify>Left = 321</P><P align=justify>Top = 107</P><P align=justify>Width = 544</P><P align=justify>Height = 375</P><P align=justify>Caption = 'Form1'</P><P align=justify>Color = clBtnFace</P><P align=justify>Font.Charset = DEFAULT_CHARSET</P><P align=justify>Font.Color = clWindowText</P><P align=justify>Font.Height = -11</P><P align=justify>Font.Name = 'MS Sans Serif'</P><P align=justify>Font.Style = []</P><P align=justify>OldCreateOrder = False</P><P align=justify>PixelsPerInch = 96</P><P align=justify>TextHeight = 13</P><P align=justify>end</P></DIR></FONT><FONT face=宋体 size=3><P align=justify>通常我们都是通过</FONT><FONT face="宋体, MS Song" size=3>CBuilder</FONT><FONT face=宋体 size=3>的窗体编辑器来设计和修改窗体,因此不建议大家手工修改</FONT><FONT face="宋体, MS Song" size=3>.dfm</FONT><FONT face=宋体 size=3>文件,这里也不再详述其格式了</P><UL><B><P align=justify><LI>资源文件</FONT><FONT size=3><FONT face="宋体, MS Song">MP3Collect.res </FONT><p></LI></UL></B><P align=justify>CBuilder</FONT><FONT face=宋体 size=3>使用标准格式的</FONT><FONT size=3>Windows</FONT><FONT face=宋体 size=3>资源文件,工程项目中所使用的资源,如位图、光标、图标等均在此文件中定义。</P><P align=justify> </P><P align=justify>本讲我们深入到了一个</FONT><FONT face="宋体, MS Song" size=3>CBuilder</FONT><FONT face=宋体 size=3>工程的内部,了解了各个文件的组成、结构和作用,特别是对于其中的</FONT><FONT face="宋体, MS Song" size=3>C++</FONT><FONT face=宋体 size=3>源文件,几乎是逐行进行了讲解。由于代码中涉及到了一些</FONT><FONT face="宋体, MS Song" size=3>C++</FONT><FONT face=宋体 size=3>术语和</FONT><FONT face="宋体, MS Song" size=3>CBuilder</FONT><FONT face=宋体 size=3>的关键词,初学编程的朋友可能会感到有些不好懂,这些朋友不妨多结合实践和其他参考资料,尽量在接触程序代码的开始就把概念搞清楚。</P></FONT> |
|