(delphi11最新学习资料) Object Pascal 学习笔记---第12章第1节 ( 类静态方法与Windows API回调)

12.1.4 类静态方法与Windows API回调

​ 静态类方法没有隐藏的Self参数意味着静态类方法可以作为回调函数传递给操作系统(例如,在Windows上)。实际上,您可以声明一个具有stdcall调用约定的静态类方法,并将其用作直接的Windows API回调,就像我在StaticCallBack示例中的TimerCallBack方法中所做的那样:

type  
  TFormCallBack = class(TForm)  
  ListBox1: TListBox;  
  procedure FormCreate(Sender: TObject);  
  private  
  class var  
  NTimerCount: Integer;  
  public  
  procedure AddToList (const AMessage: string);  
  class procedure TimerCallBack(hwnd: THandle;  
    uMsg, idEvent, dwTime: Cardinal); static; stdcall;  
  end;

​ 类数据被用作回调计数器。OnCreate处理器通过将地址传递给静态类过程来调用SetTimer API:

procedure TFormCallBack.FormCreate(Sender: TObject);  
var  
  Callback: TFNTimerProc;  
begin  
  NTimerCount := 0;  
  Callback := TFNTimerProc(@TFormCallBack.TimerCallBack);  
  SetTimer(Handle, TIMERID, 1000, Callback);  
end;

注解:TFNTimeProc的参数是一个方法指针,这就是为什么方法的名称要以@开头或者通过使用Addr函数来获取方法地址。这是因为我们需要获取方法的地址,而不是执行方法。

​ 现在实际的回调函数增加了计时器并更新了窗体,通过引用相应的全局变量来指代它——这应该避免,但需要在演示中增加一些复杂性,因为类方法不能将窗体作为Self引用:

class procedure TFormCallBack.TimerCallBack(  
  hwnd: THandle; uMsg, idEvent, dwTime: Cardinal);  
begin  
  try  
    Inc(NTimerCount);  
    FormCallBack.AddToList(  
      IntToStr(NTimerCount) + ' at ' + TimeToStr(Now));  
  except on E: Exception do  
    Application.HandleException(nil);  
  end;  
end;

​ try-except块在那里是为了避免任何异常被发送回Windows——这是您必须对回调或DLL函数一致遵守的规则。

12.1.5 类属性

使用静态类方法的原因之一是实现类属性。什么是类属性?与标准属性一样,类属性是一个与读写机制关联的符号。与标准属性不同的是,类属性与类相关,并且必须使用类数据或静态类方法来实现。TBase 类(再次来自 ClassStatic 示例)用这两种方式中定义了两个类属性:

type
  TBase = class
  private
    class var
      FMyName: string;
  public
    class function GetMyName: string; static;
    class procedure SetMyName(Value: string); static;
    class property MyName: string read GetMyName write SetMyName;
    class property DirectName: string read FMyName write FMyName;
  end;

在这个例子中,TBase 类有两个类属性,一个是 MyName,它通过类方法 GetMyName 和 SetMyName 进行读写,另一个是 DirectName,它直接读写类变量 FMyName。

12.1.6 带有实例计数器的类

​ 类数据和类方法可用于保存类整体方面的信息。这种类型的信息的一个示例可以是该类创建的实例总数或当前存在的实例数。CountObj 示例演示了这种情景。该程序并不是非常有用,因为它只关注一个特定的问题。目标对象有一个简单的类,只存储一个数值:

type
  TCountedObj = class(TObject)
  private
    FValue: Integer;
  private
    class var
      FTotal: Integer;
      FCurrent: Integer;
  public
    constructor Create;
    destructor Destroy; override;
    property Value: Integer read FValue write FValue;
  public
    class function GetTotal: Integer;
    class function GetCurrent: Integer;
  end;

​ 每次创建对象时,程序都会递增两个计数器。每次销毁对象时,当前计数器都会减少:

constructor TCountedObj.Create(AOwner: TComponent);
begin
  inherited Create;
  Inc(FTotal);
  Inc(FCurrent);
end;

destructor TCountedObj.Destroy;
begin
  Dec(FCurrent);
  inherited Destroy;
end;

​ 可以在不引用特定对象的情况下访问类信息。实际上,可能在某个时刻内存中没有对象:

class function TCountedObj.GetTotal: Integer;
begin
  Result := FTotal;
end;

​ 可以使用类似以下的代码显示当前状态:

Label1.Text := TCountedObj.GetCurrent.ToString + '/' + TCountedObj.GetTotal.ToString;

​ 在演示中,这段代码在一个定时器中执行的,它更新一个标签,因此它不需要引用任何特定的对象实例,也不是直接由任何手动操作触发的。示例中的按钮只是创建和释放一些对象,或者将一些对象保留在内存中(实际上,该程序存在一些潜在的内存泄漏)。

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Delphi XE是一种基于Object Pascal编程语言的集成开发环境(IDE),用于开发Windows平台上的应用程序。Delphi编程中的重要概念,它是面向对象编程的基础。 在Delphi XE中,用于封装数据和方法,以创建可重用的代码块。一个可以有属性和方法,属性用于访问和修改对象的数据,而方法用于执行特定的操作。通过使用和对象,可以实现代码的模块化和组织,以提高代码的可维护性和重用性。 在学习Delphi XE的编程时,需要掌握以下几个关键概念: 1. 的定义:使用class关键字来定义一个,可以在中声明属性和方法。 2. 对象的创建:通过使用来创建对象,可以通过实例化的方式来创建对象,并使用对象来调用中的方法和访问属性。 3. 继承与多态:Delphi XE支持继承和多态的特性,允许一个从另一个继承属性和方法,并可以通过多态的方式重写父的方法。 4. 的访问控制:可以使用访问修饰符(如private、protected、public、published)来控制中属性和方法的访问权限。 通过深入学习Delphi XE的编程,可以掌握面向对象编程的核心思想和技巧,能够更好地利用Delphi XE的特性和功能来开发高质量的应用程序。同时,熟练掌握编程还能够提高代码的可读性和可维护性,使代码更易于理解和修改。 综上所述,Delphi XE的学习学习Delphi编程的重要内容。通过深入了解的概念、属性、方法、继承、多态和访问控制等知识点,可以编写出更高效、可扩展和易维护的应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值