在Lazarus下的Free Pascal编程教程——用向导创建一个使用LCL和FCL组件的项目(pTetris)
0.前言
我想通过编写一个完整的游戏程序方式引导读者体验程序设计的全过程。我将采用多种方式编写具有相同效果的应用程序,并通过不同方式形成的代码和实现方法的对比来理解程序开发更深层的知识。
了解我编写教程的思路,请参阅体现我最初想法的那篇文章中的“1.编程计划”和“2.已经编写完成的文章(目录)”:
学习编程从游戏开始——编程计划(目录) - lexyao - 博客园
了解不同方式实现同样效果的差异,请阅读以下文章:
- 在CodeBolcks+wxWidgets下的C++编程教程——用向导创建一个wxWidgets项目(xTetris) - lexyao - 博客园
- 在CodeBolcks+wxWidgets+wxSmith下的C++编程教程——用向导创建一个wxWidgets项目(sTetris) - lexyao - 博客园
- 在CodeBolcks+Windows API下的C++编程教程——用向导创建一个Windows GUI项目(aTetris) - lexyao - 博客园
- 在CodeBolcks+Windows API下的C++面向对象的编程教程——用面向对象的方法改写用向导创建一个Windows GUI项目(oTetris) - lexyao - 博客园
- 在Lazarus下的Free Pascal编程教程——用向导创建一个使用使用LCL和FCL组件的项目(pTetris) - lexyao - 博客园
在这篇文章里,我主要讲述以下几个方面的内容:
- 使用向导新建一个Free Pascal应用程序(pTetris)
- 向导为我生成的项目文件pTetris与sTetris、xTetris有什么不同
- 修改pTetris项目的窗口标题
- 给pTetris项目添加菜单和响应菜单事件的代码并实现与xTetris一致的视觉效果
- 给pTetris项目更换成与xTetris一致的图标
- 给pTetris项目添加添加状态栏并实现与xTetris一致的视觉效果
- 结束语
1.使用向导新建一个Free Pascal应用程序(pTetris)
在开始下面的内容之前,我假定你已经安装了Lazarus程序开发环境,测试使用Lazarus创建第一个程序成功编译运行,并且了解了Pascal语言的基础知识和使用LCL和FCL组件编写Pascal程序的知识。
如果你还有哪一方面没有做到,请阅读下面的文章:
- 从Delphi到Lazarus——安装最新版的Lazarus - lexyao - 博客园:搭设Lazarus开发平台(安装)
- 从Delphi到Lazarus——Lazarus开发环境使用入门教程 - lexyao - 博客园:使用Lazarus的经验,包括一些有用的链接
- Basic Pascal Tutorial/zh CN - Lazarus wiki:系统地讲述Pascal语言编程的基础知识
- Pascal 教程:系统地讲述Pascal语言编程的基础知识
在开始下面的内容之前,你还需要阅读我写的以下文章。在以下文章中有创建应用程序xTetris、sTetris的全部内容,而本篇文章中创建应用程序pTetris的过程、解读、修改等都要与xTetris、sTetris进行对比,从对比来看C++编程与Pascal编程的差异,感受Pascal带来的强大震撼。
在CodeBolcks+wxWidgets下的C++编程教程——用向导创建一个wxWidgets项目(xTetris) - lexyao - 博客园
在CodeBolcks+wxWidgets+wxSmith下的C++编程教程——用向导创建一个wxWidgets项目(sTetris) - lexyao - 博客园
使用向导新建一个Pascal应用程序的操作步骤如下:
第一步:点击主菜单:[文件->新建...]打开“新建”窗口
第二步:在窗口中选择[项目->应用程序],然后点击[确定]按钮
经过这两步之后,一个应用程序pTetris项目便创建完成了。
新建的项目名为Project1,只有一个名为Form1的主窗口和一个名为Unit1代码文件。不过这个项目没有保存,只是在内存中的。不像C++开发环境那样创建一个新项目后直接保存到文件中了。
所以,要形成文件还需要第三步。
第三步、点击菜单[文件->保存],在保存文件窗口中完成以下操作:
- 建立保存文件的文件夹。我的项目保存在D:\Pas\Tetris中
- 将文件project1.lpi保存为pTetris.ipi
- 将文件unit1.pas保存为pTetrisMain.pas
在资源管理器中打开D:\Pas\Tetris,你会看到七个文件,我们需要关注的只有项目(.lpr或.ipi)、窗体(.lfm)、代码(.pas)文件。
扩展名为.ipi和lpr的项目文件的内容我们不用管它,只要记住文件名就行了。下次打开这个项目的时候就是要打开这个文件。
扩展名为.lfm窗体文件是xml格式的文本文件,感兴趣的可以用记事本打开,但千万不要修改。窗体在Lazarus中以所见即所得的形式呈现,比wxSmith更直观。
扩展名是.pas代码文件也是文本文件,这是我们要关注的,我们编写程序的代码就保存在这个文件中。
主程序文件pTetris.lpr的代码如下,这是Pascal程序的入口:
program pTetris; {$mode objfpc}{$H+} uses {$IFDEF UNIX} cthreads, {$ENDIF} {$IFDEF HASAMIGA} athreads, {$ENDIF} Interfaces, // this includes the LCL widgetset Forms, pTetrisMain { you can add units after this }; {$R *.res} begin RequireDerivedFormResource:=True; Application.Scaled:=True; Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; end.
主窗口文件pTetrisMain.pas的代码如下,看上去比C++的文件要简单很多,下一步我们增加的功能都会集中在这里:
unit pTetrisMain; {$mode objfpc}{$H+} interface uses Classes, SysUtils, Forms, Controls, Graphics, Dialogs, Menus, ComCtrls; type { TForm1 } TForm1 = class(TForm) private public end; var Form1: TForm1; implementation {$R *.lfm} end.
编译运行项目,你会看到一个很干净的小窗口,里面什么也没有。
2.向导为我生成的项目文件pTetris与sTetris、xTetris有什么不同
跟使用C++编写的项目相比,界面元素跟sTetris项目的差不多,只是尺寸、标题、颜色、图标不一样。
与xTetris相比,除了上述不一致外,还缺少状态栏。
要想做到与xTetris项目一致的外观,需要做以下修改:
- 更改标题栏文字
- 添加图标
- 添加菜单及菜单事件处理函数
- 添加状态栏,并分两栏、加文字
下面就按这几个方面进行修改。
3.修改pTetris项目的窗口标题
在Lazarus中,修改窗体标题栏文字有两种方式:代码方式和属性列表方式。我们选择使用属性列表修改方式。
为了保持良好的编程习惯,我们还需要做一个修改:
- 点击Lazarus左上角的组件列表中的Form1,列表下面属性列表显示出窗体Form1的属性。
- Form1的属性列表中找到Name属性,将其中的“Form1”改为“frmMain”。你会看到代码编辑器里的定义主窗体类的代码中的TForm1自动改成了TfrmMain,定义主窗体的变量变成了frmMain: TfrmMain。
经过修改以后在代码中就可以使用变量名frmMain作为窗体的名字了。
完成修改后按F12键显示出窗体,你会看到你添加的文字已经出现在设计中的窗体上了。这是真正的所见即所得。点击工具栏中的编译运行图标,pTetris项目编译后运行,出现主窗口,标题栏上出现了修改后的文字,跟设计时的效果是一样的。
4.给pTetris项目更换成与xTetris一致的图标
在属性列表中修改窗体的Name属性的时候,你会看到在它的上面有一个Icon,这是一个修改图标的地方。
- 点击Icon的右边的格子,会出现一个有三个点的按钮,点击这个按钮,打开添加图标的窗口。
- 添加窗口中的[加载]按钮,选择要添加的图标,然后点击[确定]按钮完成添加图标的操作。
添加图标后按F12键,显示出窗体,你会看到窗体左上角的图标变成了你添加的图标。
编译运行pTetris项目,运行后的窗体上显示了你添加的图标,而电脑桌面下面任务栏上的图标还是原来的熊爪,没有变成你添加的图标。这说明这种方式添加图标没有达到目的。
在采用其他的方法添加图标之前,重新打开添加图标的窗口,点击[清除]按钮删除添加的图标,然后[确定],窗体的图标恢复了原来的熊头图标。
下面我们选择另一种添加图标的方法。
- 点击主菜单[项目->项目选项],打开项目选项窗口
- 点击左边的[项目选项],再点击右边的[加载图标],选择你要添加的图标,然后点击[确定]按钮,完成添加图标的操作。
这样添加的图标是应用程序的图标,而不是主窗体的图标,所以这个图标在设计时是不会显示在窗体上的,到了运行时才会显示到主窗体上。
这时再编译运行pTetris项目,你会发现任务栏和窗体左上角都是你添加的图标。这说明达到预期的目的了。
5.给pTetris项目添加菜单和响应菜单事件的代码并实现与xTetris一致的视觉效果
在Lazarus中,主菜单也是组件,需要按着添加组件的方法添加到设计中的窗体中。
添加组件有两种方法。两种方法的操作不同,但效果是一样的:
在组件面板中点击要添加的组件图标,这时窗体设计器显示出设计时的窗体,点击窗体中要放置组件的地方,组件就加入窗体中了。左上角的组件列表中也会同时显示出已经加入的列表的名字
在右侧的组件列表中双击要添加的组件的类名称,你会看到组件添加到了左上角的组件列表中了,而设计时的窗体虽然没有出现,组件确实已经添加上去了。你需要按F12显示出设计时的窗体,将添加的组件拖动到需要的位置
下面我们开始添加菜单的操作:
第一步、在右侧的组件列表中选择“调色板”页面,在Standard组中找到TMainMenu并双击它,这时看到左上角出现了主菜单的名字和类型,主窗体属性列表的Menu属性也自动添加了你刚刚加入的主菜单的名字MainMenu1。
第二步、鼠标右击组左上角组件列表中的主菜单,从弹出菜单中选择[菜单编辑器...]打开菜单编辑器窗口
第三步、按着你要添加菜单的样式点击“添加菜单项”或“添加子菜单”,直到你添加的项目全部完成。一个所见即所得的主菜单出现在了菜单设计器中
第四步、选择要修改的菜单项,在属性列表中将它的Name和Caption改成你需要的名字,一个菜单完成了。
这时你可以编译运行看一下效果,运行后的跟设计器中的应该是一样的。
第五步、选中要添加事件处理程序的菜单项,在属性列表中切换到[事件]页,双击要添加的事件对应的右边栏目,这个事件的事件处理函数就添加上了。你不但可以在事件列表中看到函数的名字,在代码中也同时添加了事件处理函数的定义和实现。你只需要在函数的实现中添加响应事件动作的代码就行了。
如果是添加菜单项的单击事件处理函数,在菜单设计器中双击菜单项也可以添加事件处理函数。
以下是添加了[退出]和[关于...]两个菜单项的事件处理函数后的代码:
unit pTetrisMain; {$mode objfpc}{$H+} interface uses Classes, SysUtils, Forms, Controls, Graphics, Dialogs, Menus, ComCtrls,LCLType ; type { TfrmMain } TfrmMain = class(TForm) MainMenu1: TMainMenu; mnFile: TMenuItem; mnHelp: TMenuItem; mnNew: TMenuItem; Separator1: TMenuItem; mnExit: TMenuItem; mnAbout: TMenuItem; StatusBar1: TStatusBar; procedure mnAboutClick(Sender: TObject); procedure mnExitClick(Sender: TObject); private public end; var frmMain: TfrmMain; implementation {$R *.lfm} { TfrmMain } procedure TfrmMain.mnExitClick(Sender: TObject); begin Close; end; procedure TfrmMain.mnAboutClick(Sender: TObject); begin MessageDlg('pTetris', Caption, mtConfirmation,[mbOk],0); Application.MessageBox (PCHAR('This is my oTetris by Win32 GUI'#$D#$A'Copyright(c) lexyao,2024'), PCHAR('pTetris' ),MB_ICONQUESTION); end; end.
上面的代码中,TfrmMain.mnAboutClick添加了两个显示提示信息的窗口。这么做只是为了演示两种方法,实际编程中不可能这么做,只保留一个就行了。
6.给pTetris项目添加添加状态栏并实现与xTetris一致的视觉效果
状态栏也是组件,同样采用添加组件的方法添加。
第一步、在右侧组件列表中找到[调色板->Commom Contrals->TStattusBar],然后双击状态栏组件到主窗体中。添加的状态栏会自动停靠在窗口的下边。
第二步、在左侧组件列表中选择状态栏组件,在属性列表中双击Items属性打开状态栏面板编辑器
第三步、点击状态栏面板编辑器的[添加]按钮,添加两个面板。选中一个面板,在属性列表中的Text行输入要显示的文字,在Width行输入面板的宽度
至此,添加状态栏、添加面板、添加面板上的文字的操作全部完成了。
此时可以看到设计时窗口的样子,也可以编译运行看到运行时窗口的样子。二者何其相似!这要比C++中wxSmith的所见即所得要好很多。
7.结束语
从上面的操作看,Lazarus的程序设计是多么简单、方便啊。比C++要好很多。
有人说,C++的功能要比其他语言强,其实这是误解。
在台式个人计算机在Apple Ⅱ的引领下风靡全球的时候,Pascal是最受欢迎的编程语言,具有不可替代的位置。直到后来C语言在营销手段上胜过了Pascal,才逐渐代替了Pascal的霸主地位。
当时美国C语言的运营商推动了美国的教育界,将C语言设置成了学校的必修课,这样年轻一代在走出校园之前就已经接受了C语言作为编程工具,从而在人数上超过了Pascal。再后来使用C语言编写的操作系统更是给C语言做了广告,夸大了C语言的影响力,最终使得C语言成了新的霸主。
不管C或者后来的C++多么受欢迎,Pascal的易学易用性始终是不可替代的,至今保留了众多的追随者。
如果想学计算机语言,从Pascal开始是一种明智的选择。
就在今年年初,Pascal的缔造者Niklaus Wirth教授离开了人世。这位设计了多种计算机语言的大师的辞世是计算机世界的巨大损失,人们会永远怀念他。