TPersistent类

TPersistent类是可视化编程的基础

TPersistent类处理的是持续性的问题,也就是将对象的信息保存在文件中,在程序重新打开后恢复原样

在Delphi项目中有.DFM文件,该文件保存了设计时建立的各个可视控件的对象信息

DFM文件保存了组件的各种处理事件的名字,而组件则实际保存着处理事件的指针

Published关键字

Published关键字:为声明的字段、属性或方法生成运行时信息RTTI,可用于动态调用。

通过Published,我们可以用从TObject中继承来的方法动态执行,主要代码如下:

MethodAddress('MethodName'): TMethod;获取指定方法名的方法所在的内存地址,即方法指针
MethodName(TMethod): string;获取指定内存地址的方法名
FieldAddress('Param Name'):Pointer获取指定字段名的地址
以上三个方法都要求指定的字段或方法由Published标识

TMethod是一个记录类型:
	type
		Record 
			Code: Pointer; //方法指针
			Data: Pointer; //类实例指针,一般为Self
		End;
TMethod可以将普通方法转换为对象方法

TNotifyEvent是一个对象方法: type procedure(Sender: TObject) of Object;
类过程是一个可以通过类调用方法的过程类型,而不必创建对象来调用,包含了一个隐含参数Self
类过程的赋值必须是类中的方法
自定义类方法:举个栗子:type MyType = function(Num: Integer): Integer of Object;

类方法的用途:不知道,待补充

//
Var method: TMethod; Evt: TNotifyEvent;
begin
	method.Code := MethodAddress('AddNum');	//获取方法指针,这里获取的是Form1(当前窗口)的AddNum方法
	method.Data := Self;
	Evt := TNotifyEvent(method);
	Evt(TObject(0));
end;

TComponent类

TComponent类继承自TPersistent类,是Delphi基础组件类库的核心类

TComponent类有一个特性,称为所有权。当创建组件时,可以把这个组件的所有权赋给一个已经存在了的组件

每个组件都要负责其拥有的组件的内存释放。这样可以解决大部分的内存管理问题,因为只要释放了一个组件,其所拥有的组件自动释放

TComponent中的一些属性和方法:

  constructor Create(AOwner: TComponent); virtual; //构造器,生成对象的同时设置其所有者
  procedure DestroyComponents; //释放拥有的组件
  function FindComponent(const AName: string): TComponent;//查找组件

  procedure InsertComponent(const AComponent: TComponent);//添加组件
  //当一个组件创建并制定其Owner后,其所有者会将这个组件插入到自己的组件列表中
  
  procedure RemoveComponent(const AComponent: TComponent);//移除组件
  
  property Components[Index: Integer]: TComponent read GetComponent;//组件列表
  //只读,利用Components属性可以获取容器或窗体内的组件引用,并进行操作
  
  property ComponentCount: Integer read GetComponentCount;//组件列表中组件的数量
  property ComponentIndex: Integer read GetComponentIndex write SetComponentIndex;//自己在所有者的组件列表中的序号
  property Owner: TComponent read FOwner; //所有者
  //Owner和Parent的区别:Owner指创建者,Parent指父容器
  //在生成组件时,制定Owner为其内存释放负责,指定Parent则是决定该组件将在那个组件上显示

Additional 控件

BitBtn
  • graph:按钮图标,只能选.BMP文件;
  • NumGraph:图标个数,一个BMP文件里可能有多个图标

    至多可完整实现4个图标,每个图标对应按钮的一个状态
    图标按顺序表示的按钮状态:第一个图标表示按钮弹起的状态;第二个图标表示按钮不可用的状态;第三个表示按钮被点击的状态;第四个表示按钮下沉的状态

  • Kind:按钮类型,根据选项会自动设置ModalResult和按钮图标、标题等
  • Layout:图标的位置
  • Spacing:图标和文字的间隔,单位为像素
SpeedButton
  • Flat:扁平化,即去掉边框凸起
  • Transparent:如果Flat = True,则可使按钮背景透明。可用来设计超链接样式的按钮
  • GroupIndex:设置该按钮的组编号
  • Down:组编号相同(至少2个按钮)的按钮只有一个点击时会显示下沉样式
  • AllowAllUp:是否允许按钮下沉后再次点击时还原
MaskEdit
  • 用途:限制用户输入
  • EditMask:格式掩码,格式解析见链接
  • MaxLength:限制输入长度,如果有设置EditMask的话该属性失效,长度以EditMask中的为准
  • CharCase:限制输入的大小写,将输入的英文自动转化为大写或小写
Image
  • 用途:显示图片,或用于当背景图片

  • Picture:设置要显示的图片

  • AutoSize:是否根据图片大小自动设置该控件的大小

  • Stretch: 是否根据控件大小缩放图片

  • Center:将图片置于控件中心

    TPicture类:

    LoadFromFile(const filePath: string)根据路径获取图片
    SaveToFile(const filePath: string)根据路径保存图片
    LoadFromClipboardFormat():不懂,待补充
    SaveFromClipboardFormat():不懂,待补充

窗体间传递信息

  • 第一种方法:frm1.label.Caption := frm2.edit.Text;
  • 第二种方法:设计一个公用单元,使frm1和frm2都引用它

快捷键

  • try + 换行:try...finally..end;
  • trye + Ctrl + J:try...except on E: Exception do ... end;

实现功能

  • 按Tab焦点转移:设置控件的TabOrder
  • TabStop:为True时按tab不会跳到该控件上
  • 按钮的Cancel属性:ModalResult := mrCancel
  • 按钮的Default属性: ModalResult := mrOk
  • Achors属性(锚点):控件相对于父控件的(akLeft\akTop\akRight\akBottom)边距是否固定

注意:当在模态框的确认按钮点击事件这里,不要用Close,因为Close会重新把ModalResult设置为MrCancel

  • 为什么在按钮点击事件里为ModalResult赋值就能做到在该事件结束后自动退出呢?

    原因与ShowModal的实现有关,点进ShowModal,前面一大堆是什么意思没看懂,但我找到了这段代码