men*_*raz 16 delphi anonymous delphi-xe
继这篇文章后,其接受的答案仍然非常神秘:
@Button1.OnClick := pPointer(Cardinal(pPointer( procedure (sender: tObject) begin ((sender as TButton).Owner as TForm).Caption := 'Freedom to anonymous methods!' end )^ ) + $0C)^;
我想知道是否有可能设计出类似于以下的最简单和优雅的方式:
Button.OnClick :=
                    AnonProc2NotifyEvent (
                    procedure (Sender: TObject)
                    begin
                      ((Sender as TButton).Owner as TForm).Caption := 'Freedom to anonymous methods!'
                    end
                      );
以便达到相同的目的,并且AnonProc2NotifyEvent是具有以下签名的Button的所有者的方法:
TOwnerOfButton = class(TForm)
  Button: TButton;
  ...
private
  ...
protected
  function AnonProc2NotifyEvent(aProc: TProc<TObject>): TNotifyEvent;
public
  ...
end;
这是可行的,如果可行,如何实施呢?
Dav*_*nan 30
这将很容易地完成工作:
type
  TNotifyEventWrapper = class(TComponent)
  private
    FProc: TProc<TObject>;
  public
    constructor Create(Owner: TComponent; Proc: TProc<TObject>);
  published
    procedure Event(Sender: TObject);
  end;
constructor TNotifyEventWrapper.Create(Owner: TComponent; Proc: TProc<TObject>);
begin
  inherited Create(Owner);
  FProc := Proc;
end;
procedure TNotifyEventWrapper.Event(Sender: TObject);
begin
  FProc(Sender);
end;
function AnonProc2NotifyEvent(Owner: TComponent; Proc: TProc<TObject>): TNotifyEvent;
begin
  Result := TNotifyEventWrapper.Create(Owner, Proc).Event;
end;
该Owner参数AnonProc2NotifyEvent是使得包装对象的寿命进行管理.没有这样的东西你会泄漏实例TNotifyEventWrapper.
传递Owner给您连接事件的组件.例如:
Button1.OnClick := AnonProc2NotifyEvent(
  Button1,
  procedure(Sender: TObject)
  begin
    (Sender as TButton).Caption := 'Clicked';
  end
);
因此,当按钮被销毁时,TNotifyEventWrapper也将被销毁.包装器对象必须至少与它所关联的事件的对象一样长.因此,Button1作为所有者的选择是自然而明显的.
为了参考这个我得到的,我研究了Barry Kelly在前面提到的SO帖子中引用的博客文章并提出了这个解决方案:
function TMainForm.Proc2NotifyEvent(const aProc: TNotifyReference): TNotifyEvent;
type
  TVtable = array[0..3] of Pointer;
  PVtable = ^TVtable;
  PPVtable = ^PVtable;
begin
  TMethod(Result).Code := PPVtable((@aProc)^)^^[3];
  TMethod(Result).Data := Pointer((@aProc)^);
end;
仍然神秘但封装,因此与初始方法相比,简化了编码器的任务.
我试着整理MethRefToMethPtr和MakeNotify并将其全部放在一个方法中.
请注意,方法的签名发生了(轻微的)更改,参数aProc变为const.
| 归档时间: | 
 | 
| 查看次数: | 6237 次 | 
| 最近记录: |