• Method pointer and regular procedure


    This is the difference between a "procedure" and a "procedure of object"

    The OnClick is defined as a TNotifyEvent:

    type TNotifyEvent = procedure(Sender: TObject) of object;

    You cannot assign a procedure to the OnClick as it is the wrong type. It needs to be a procedure of object.

    You can wrap your procedures into a class. This class might look like this in a separate unit:

    unit CommonUnit;
    
    interface
    
    uses
      Dialogs;
    
    type
      TMenuActions = class // dummy class to hold event handlers
      public
        class procedure BrowseCategoriesClick(Sender: TObject);
      end;
    
    implementation
    
    { TMenuActions }
    
    class procedure TMenuActions.BrowseCategoriesClick(Sender: TObject);
    begin
      ShowMessage('BrowseCategoriesClick');
    end;
    
    end

    And to assign the action to a menu item in a different unit is enough to use this:

    uses
      CommonUnit;
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      PopupMenuItem1.OnClick := TMenuActions.BrowseCategoriesClick;
    end;

    Update:

    Updated to use class procedures (instead of object methods) by David's suggestion.
    For those who want to use the object methods with the need of object instance, follow this version of the post.

    unit CommonUnit;
    
    interface
    
    uses
      Dialogs;
    
    type
      TMenuActions = class
      public
        procedure BrowseCategoriesClick(Sender: TObject);
      end;
    
    var
      MenuActions: TMenuActions;
    
    implementation
    
    { TMenuActions }
    
    procedure TMenuActions.BrowseCategoriesClick(Sender: TObject);
    begin
      ShowMessage('BrowseCategoriesClick');
    end;
    
    initialization
      MenuActions := TMenuActions.Create;
    finalization
      MenuActions.Free;
    
    end.

    Use a procedure as a fake method

    procedure MyClick(Self, Sender: TObject);
    begin
      //...
    end;
    
    var
      M: TMethod;
    begin
      M.Data := nil;
      M.Code := @MyClick;
      MyMenuItem.OnClick := TNotifyEvent(M);
    end;

    use record methods ( global variable )

    type
      TMyEventHandler = record
        procedure OnConnectionError(Sender: TObject; E: EDAError; var Fail: Boolean);
        procedure OnConnectionLost(Sender: TObject; Component: TComponent; ConnLostCause: TConnLostCause; var RetryMode: TRetryMode);
      end;
    
    procedure TMyEventHandler.OnConnectionError(Sender: TObject; E: EDAError; var Fail: Boolean);
    begin
      ....
    end;
    
    procedure TMyEventHandler.OnConnectionLost(Sender: TObject; Component: TComponent; ConnLostCause: TConnLostCause; var RetryMode: TRetryMode);
    begin
      ....
    end;
    
    var
      EventHandler: TEventHandler;
    
    ......
    
    mydb.OnError := EventHandler.OnConnectionError;
    mydb.OnConnectionLost := EventHandler.OnConnectionLost;

  • 相关阅读:
    cinder支持nfs快照
    浏览器输入URL到返回页面的全过程
    按需制作最小的本地yum源
    创建可执行bin安装文件
    RPCVersionCapError: Requested message version, 4.17 is incompatible. It needs to be equal in major version and less than or equal in minor version as the specified version cap 4.11.
    惠普IPMI登陆不上
    Linux进程状态——top,ps中看到进程状态D,S,Z的含义
    openstack-neutron基本的网络类型以及分析
    openstack octavia的实现与分析(二)原理,架构与基本流程
    flask上下文流程图
  • 原文地址:https://www.cnblogs.com/shangdawei/p/3051802.html
Copyright © 2020-2023  润新知