2016年第3版
第1章 Delphi基础知识
Delphi发展历程
- 早期版本(Borland/Inprise 时期)
- 1995年,Borland发布Delphi1.0,首次发布,支持 16 位 Windows 开发,基于 Object Pascal 语言
- 1996年,Borland 发布Delphi 2.0,升级为 32 位编译器,支持客户端-服务器(C/S)数据库开发
- 1997年,Borland 发布 Delphi 3.0语法,引入 接口(Interface)机制,IDE 首次提供 Code Insight 智能代码提示。
- 1998年,Borland更名 Inprise,发布 Delphi 4.0,加入 动态数组 和 方法覆盖,IDE 增强调试能力,支持 代码模板。
- 1999年,Inprise 发布 Delphi 5.0,优化 IDE 和调试器,推出 TeamSource 团队协作工具,简化 Internet 开发,增强数据库支持。
- 2001年,Inprise重新更名Borland,发布Delphi 6.0,支持 Web Service,发布跨平台的 Kylix 1.0(Linux 开发)和 CLX 组件库。
- 2002年,Borland 发布 Delphi 7.0,为 .NET 过渡做准备,引入 IntraWeb 支持 Internet 开发,集成 Indy 网络组件 和 Rave Report,支持 UML 和 XP 开发模式。
- 2003年,Borland发布Delphi 8.0(Delphi .NET),专为 .NET 设计,兼容 C# 能力,保留 Delphi 易用性(过渡版本)。
- 2004年,Borland发布Delphi 9.0,正式名称为Delphi 2005。语法新增 inline 和 for-in 循环,支持泛型。
- 2005年,Borland 发布 Delphi 10.0,发布名称为Borland Developer Studio(BDS)2006。集成C++Builder; ECO(Enterprise Core Objects)升级到ECO III;集成 Together for Delphi,可以在同一个IDE中进行UML开发;QA Audits和QA Metrics可以快速地把握专案的设计和代码的质量。
- 2006年,Borland 将BDS 2006拆分成几个独立的版本(Delphi for Win32、Delphi for NET、C#、C+Builder),而且不能同时安装两个不同的版本。由于Borland的IDE生产部分独立成为一家名为CodeGear的公司,所以这个版本是以Borland名义推出的最后一个版本。
- CodeGear 时期(2007年)
- 2007年,CodeGear发布Delphi 2007(CodeGear Delphi 11.0),代码编辑器增强,支持 Unicode,改进调试器性能。
- Embarcadero 时期(2008年至2025)
- 2008年,Borland正式宣布将CodeGear子公司出售给 Embarcadero(英巴卡迪诺)技术公司。
- 2008年,Embarcadero 发布 CodeGear Delphi 2009 Pre-release版。,支持 Unicode 字符集,改进跨平台兼容性。
- 2009年,Embarcadero 发布 CodeGear.RAD.Studio.2010版,首次整合 Delphi、C++Builder、HTML5 等工具,支持多语言开发。
- 2010年,Embarcadero发布Delphi XE,强化 VCL(视觉组件库)和数据库支持,优化性能。
- 2011年,Embarcadero 发布 Delphi XE2 RTM,首次支持 跨平台开发(Windows、macOS、iOS、Android)。
- 2012年,Embarcadero 发布 Delphi XE3,增强移动应用开发,支持触摸屏和传感器。
- 2013年4月,Embarcadero发布Delphi XE4,改进 FireMonkey(FMX)框架,支持更多移动平台。
- 2013年9月,Embarcadero发布Delphi XE5,支持 单一代码库开发(Windows、OS X、iOS、Android、Linux)。
- 2014年5月,Embarcadero发布Delphi XE6,集成 云端开发 和物联网(IoT)支持。
- 2014年9月,Embarcadero 发布 Delphi XE7,扩展物联网设备支持(如 Raspberry Pi)和跨平台数据库。
- 2015年5月,Embarcadero发布Delphi XE8,完善移动、云端和 IoT 开发,支持 Windows 10 UWP 应用开发。
- 年份命名版本(2015年至2025)
- 2015年,Delphi 10 Seattle,采用 AppMethod 云服务,增强跨平台部署能力。
- 2016年,Delphi 10.1 Berlin,支持 64 位 macOS 和 Linux 服务器端开发。
- 2017年,Delphi 10.2 Tokyo,强化 REST 服务和 Docker 容器支持。
- 2018年,Delphi 10.3 Rio,改进 FireMonkey 性能,支持 Windows 10 后台任务。
- 2019年,Delphi 10.4 Sydney,支持 .NET Core 和 Python 脚本集成。
- 2020年,Delphi 11 Alexandria,引入 LiveBindings 和 增强型数据感知,优化移动端性能。
- 2021年,Delphi 12
- 2022年,Delphi 12.1
- 2023年,Delphi 12.2
- 2024年,Delphi 12.3
集成开发环境
当对窗体设计器中的可视化组件进行操作时,Delphi 会自动生成Object Pascal源代码。
当用 File|New|VCL Forms Application 命令创建一个新的项目时,将看到屏幕上出现一个空白的窗体设计器,同时,代码编辑器中会自动出现如下代码,{}
,//
是注释:
// Unit1.pas 文件内容 ,修改 Unit.pas 为 MainForm.pas, 对应的dfm文件也会自动从从 Unit1.dfm修改为 MainForm.dfm
//与任何窗体对应的源代码模块都驻留在单元文件中。
//虽然每个窗体都对应着一个单元文件,但并不是每个单元文件都对应着一个窗体
unit MainForm; // 原始内容: unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs;
type
// 窗体对象是从TForm类继承下来的
TForm1 = class(TForm)
// Delphi已经清楚地标出了可以插入公共(Public)和私有(Private)变量的地方
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
// Pascal语言中的$R指令用于加载一个外部资源文件。
// 下面这一行表示把*.dfm(代表Delphi窗体)文件链接到可执行文件中。
// *.dfm文件中包含在窗体设计器中创建的表单的二进制代码。
// 其中的*不代表通配符,而是表示与当前单元文件同名的文件。
// 例如,假设上面一行是在一个名为MainForm.pas的文件中,则*.dfm就代表名为 MainForm.dfm的文件。
{$R *.dfm}
end.
项目文件的扩展名是dpr(代表Delphi Project),它只是一个带有不同扩展名的Pascal源文件。可以修改项目名称,如 ProjectDelphiTest.dproj,对应的项目文件也会被修改为:ProjectDelphiTest.dpr。
项目文件中有程序的主要部分,与其他版本的Pascal不同,大多数的编程工作都是在单元文件中完成的,而不是在主模块(dpr)中。
可以执行Project|View Source 命令把项目源文件,如这里的ProjectDelphiTest.dpr,调入代码编辑器:
program ProjectDelphiTest;
uses
//当向应用程序中添加表单和单元时,它们将出现在项目文件的uses子句中。
Vcl.Forms,
//在uses子句中的单元文件名之后,相应表单的名字将以注释的形式出现。
//如果搞不清楚哪个单元对应哪个文件,可以在“项目管理器”区域中查询。
MainForm in 'MainForm.pas' {Form1};
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
- 每个表单都对应着一个单元文件,而有的单元文件却只有代码而不对应任何表单。
- 在Delphi中,大部分情况下都是对单元文件进行编程,几乎不需要编辑.dpr文件。
基于组件的编程思想
Delphi是一种典型的基于组件的编程工具。在介绍组件编程之前,首先简要回顾软件设计方法的发展史,以便更好地理解基于组件的编程思想。
- 在早期DOS操作系统和C语言主导的时代,“数据结构+算法”成为构建软件的唯一方式,然而这种扁平的API组织结构带来的现实逻辑与机器实现之间的巨大鸿沟让人无法忍受,近乎相同的软件被低效地一遍一遍重写。
- 接着,千呼万唤始出来的C++语言和面向对象技术,一时间成为人们的口头语;绚丽多彩的Windows成为人们的栖息地;MFC类库及由其主导开发的各种桌面软件成为C++历史上的极盛时期。然而,随着软件规模越来越大,面向Web应用的需求越来越高,源代码级的对象复用显然已经不能满足需要。软件开发迫切需要一个面向Internet的异构体系,为软件提供像IC电路元件一样可插拔 的标准封装和复用方式的组件构造平台。于是20世纪90年代中期开始流行一种崭新的程序设计概念:软件可以由可互换的组件构成,一套组件可以装配出音频系统或者家庭影院。这就是基于组件的编程思想。
- 一般来讲,组件是指通过公开的属性方法、事件,让其他的程序设计者可以重复使用的一种经过编译的二进制文件,其文件名可以是.OCX或者是.dll,如命令按钮、复选框、单选框、滚动条等都是常见的组件。
- 同一个组件可以嵌入各种不同的应用程序之中,因而可以方便地通过改写组件的属性和事件来定制组件,使它适用于不同的应用程序,从而极大地提高编程的效率和程序的复用率。
- Delphi中有一个庞大的可视化组件库(VCL),其中总共包括五百多种组件,涉及程序设计的各个领域。其中任何一种组件一般都包括属性、方法、事件等信息,可以对其进行设定或者重载,“装配”自己的软件。当然用户也可以定义自己的组件
简单的Delphi程序设计
一般情况下,Delphi XE8编写应用程序包括新建应用程序、设置窗体属性、添加组件、设置组件属性、添加事件、编写事件响应代码和编译运行等几大步骤。下面以一个简单的例子来介绍这些过程。
- 启动Delphi ,执行 File|New|VCL Forms Application 命令,新建一个应用程序。
- 单击 Object Inspector(对象观察器)项,在打开的对话框中选择Properties选项卡,在Caption文本框中输入窗体的新标题“窗口”,name由Form1修改为 FormMain
- 设置组件属性,添加三个按钮
- Buttonl caption 窗口放大 按钮的标题
- Button2 caption 窗口缩小 按钮的标题
- Button3 caption 退出 按钮的标题
- 添加事件:选中窗体中要添加事件的组件,激活对象观察器,并选择Events选项卡。在对象观察器中单击要添加的事件,如单击OnClick事件,在其右侧的文本框中输入事件的响应函数名称,如 Button1Click,然后按回车键即可。用同样的方法添加响应函数 Button2Click 和Button3Click。
- 编写事件响应代码:先选定要编写事件响应代码的组件,再打开Object Inspector中的Events选项卡,双击要编写响应代码的事件右侧的空白部分,这里是双击OnClick事件右侧的空白部分,进入代码编辑窗口。这个过程也可以在窗体中通过双击Button组件来完成。
// Unit1.pas 文件内容 ,修改 Unit.pas 为 MainForm.pas, 对应的dfm文件也会自动从从 Unit1.dfm修改为 MainForm.dfm
// 与任何窗体对应的源代码模块都驻留在单元文件中。
// 虽然每个窗体都对应着一个单元文件,但并不是每个单元文件都对应着一个窗体
unit MainForm; // 单元文件名,原始内容: unit Unit1;
interface // 接口关键字,用它来标识文件所调用的单元文件
uses // 使用的公共单元
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type // 定义程序所使用的组件以及组件所对应的事件
// 窗体对象是从TForm类继承下来的
TFormMain = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
// Delphi已经清楚地标出了可以插入公共(Public)和私有(Private)变量的地方
private // 定义私有变量和私有过程
{ Private declarations }
public // 定义共有变量和共有过程
{ Public declarations }
end;
var // 定义程序使用的公共变量
FormMain: TFormMain;
implementation // 程序代码实现部分
// Pascal语言中的$R指令用于加载一个外部资源文件。
// 下面这一行表示把*.dfm(代表Delphi窗体)文件链接到可执行文件中。
// *.dfm文件中包含在窗体设计器中创建的表单的二进制代码。
// 其中的*不代表通配符,而是表示与当前单元文件同名的文件。
// 例如,假设上面一行是在一个名为MainForm.pas的文件中,则*.dfm就代表名为 MainForm.dfm的文件。
{$R *.dfm}
procedure TFormMain.Button1Click(Sender: TObject);
begin
FormMain.Height := FormMain.Height + 10;
FormMain.Width := FormMain.Width + 10;
end;
procedure TFormMain.Button2Click(Sender: TObject);
begin
FormMain.Height := FormMain.Height - 10;
FormMain.Width := FormMain.Width - 10;
end;
procedure TFormMain.Button3Click(Sender: TObject);
begin
Application.Terminate;
end;
end.
示例:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
lblTextInput: TLabel;
lblTextLength: TLabel;
edtTextInput: TEdit;
edtTextLength: TEdit;
btnExit: TButton;
procedure btnExitClick(Sender: TObject);
procedure edtTextInputChange(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
intTextLen: Integer = 0; // 字符串长度
implementation
{$R *.dfm}
procedure TForm1.btnExitClick(Sender: TObject);
begin
Application.Terminate;
end;
procedure TForm1.edtTextInputChange(Sender: TObject); // 随着输入字符串长度的变化而变化
begin
intTextLen := edtTextInput.GetTextLen;
edtTextLength.Text := IntToStr(intTextLen);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Form1.Position := poDesktopCenter;
Form1.Caption := '字符长度测试';
lblTextInput.Caption := '请输入字符:';
lblTextLength.Caption := '字符长度:';
edtTextInput.Text:='';
edtTextLength.ReadOnly := True;
btnExit.Caption := '退出';
end;
end.
不能改变大小的窗体:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormResize(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
// 定义存储初始长宽的变量
formHigh: Integer;
formWidth: Integer;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
formHigh := Form1.Height;
formWidth := Form1.Width;
Form1.Position:=poDesktopCenter;
end;
procedure TForm1.FormResize(Sender: TObject);
begin
Form1.Height := formHigh;
Form1.Width := formWidth;
end;
end.
正文完