type… procedure of object



     A procedure of object is a procedure reference for procedures contained in class instances. When calling procedures that are members of a class, the implict Self reference must be passed with the other parameters. Using procedure of object tells the compiler to store the Self reference with the procedure address inside the procedure reference, so that when the procedure is called via the procedure reference, the Self reference will be automatically passed.

     In the code snippet you provided, TFinishedCaptureEvent is defined as a procedure of object, meaning that any variables created of its type will contain 2 values: the Self value and the procedure address. When this variable is assigned to, in particular when the assignment is inside a class, the compiler will automatically set the Self value inside this variable to the instance of the class that contains the procedure being assigned to the variable. When the variable is called (FOnFinishedCapture(False)), the compiler automatically passes the correct Self value back to the procedure that was assigned to this variable.



      Let's break this down into two parts to be easier to understand. First, procedure(AFinished: Boolean) isn't a boolean variable, it's a reference to a procedure that takes a boolean as a parameter. It's basically a procedure header, except without the procedure name because this is just a type definition. Any procedure that matches this signature can be assigned to this variable.

     The of object part means that this isn't just a procedure reference, but a method reference; it has to belong to an object. The compiler needs to know the difference so that it can store the self pointer for the object together with the procedure pointer so it can be invoked properly, as the other posters have pointed out.

     Basically, this is declaring a new event handler, and it's a pretty common pattern in Delphi. It's the same thing that the VCL does all over the place. When you create a button and assign an OnClick handler, it has to be a procedure (Sender: TObject) of object;. Your form gives the button a method reference referring to itself and the event handler procedure, and then the button uses that information to invoke the handler on the form when someone clicks it.

    This code is doing the same thing. It's providing a way for some external object to be notified when DoUpdateMessage runs, using the standard Delphi idiom for event notification.


1   type Name = Function header of Object;
2   type Name = Procedure header of Object;
Description
The Object keyword has one principle use - to qualify a function or procedure data type, allowing it to refer to an equivalent object method.
 
The older, obsolete use (not given in the syntax above), was used to create an object (now we use a class constructor).
 
Variables of function and procedure types can be used as pointers, in effect, to functions and procedures with the same argument and return value profile (signature).
 
For example :
 
function AddUp(a, b : Integer) : Integer;
...
type
  TFunc = function(a, b : Integer) : Integer;
var
  func : TFunc;
  c : Integer;
begin
  func := AddUp;
  c := func(12, 34);   // Invokes AddUp function
end;

 
With the Of Object qualifier, the subroutine type must be set to refer to a method in an object. For example :
 
type
  TMyClass = class
  public
    procedure StoreName(name : string);
  end;

  TProc = procedure(name : string) of Object;
var
  proc    : TProc;
  myClass : TMyClass;
begin
  myClass := TMyClass.Create;
  proc    := myClass.StoreName;
  proc('My name');  // Invokes myClass.StoreName
end;
Notes
Such subroutine types are in effect pointers to both  the code and data parts of the method.
Related commands
Class  Starts the declaration of a type of object class
Function  Defines a subroutine that returns a value
Procedure  Defines a subroutine that does not return a value
TObject  The base class type that is ancestor to all other classes


Example code : Accessing an object method directly and indirectly
// Full Unit code.
// -----------------------------------------------------------
// You must store this code in a unit called Unit1 with a form
// called Form1 that has an OnCreate event called FormCreate.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  // Define a simple class
  TSimple = class
  private
    name : string;
  public
    function GetName : string;
    constructor Create(name : string);
  end;

  // The form class itself
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

// Create a simple object
constructor TSimple.Create(name: string);
begin
  // Save the passed string
  self.name := name;
end;

// Returns the simple name
function TSimple.GetName: string;
begin
  Result := name;
end;

// Main line code
procedure TForm1.FormCreate(Sender: TObject);
type
  TNameFunc = Function : string of Object;

var
  simple   : TSimple;
  nameFunc : TNameFunc;

begin
  // Create a simple object
  simple := TSimple.Create('Brian');

  // Show the object name
  ShowMessage('Name accessed directly = '+simple.GetName);

  // Now refer to this method indirectly
  nameFunc := simple.GetName;

  // Show the object name
  ShowMessage('Name accessed indirectly = '+nameFunc);
end;
end.
   Name accessed directly = Brian
   Name accessed indirectly = Brian
 


参考:http://stackoverflow.com/questions/4626614/delphi-please-explain-this-type-procedure-of-object

          http://www.delphibasics.co.uk/RTL.asp?Name=Object

          http://docwiki.embarcadero.com/RADStudio/XE7/en/Procedural_Types


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值