Delphi, how to control function pointers during assignment? I.e. Storing value of pointer instead of calling pointer?

This seems like a basic question, but I tried searching and couldn’t find an answer.

I have a function pointer declared like this:

THandleTableCellEdit = function(InitValue, FileNum, IENS, FieldNum : string;
                                  GridInfo : TGridInfo;
                                  var Changed, CanSelect : boolean;
                                  ExtraInfo : string = '';
                                  ExtraInfoSL : TStringList = nil;
                                  Fields : string = '';
                                  Identifier : string = '') : string;

I have a matching function to be used with such a function pointer:

function HandlePtrEdit(InitValue, FileNum, IENS, FieldNum : string;
                        GridInfo : TGridInfo;
                        var Changed, CanSelect : boolean;
                        ExtraInfo : string; ExtraInfoSL : TStringList;
                        Fields : string;
                        Identifier : string) : string;

I want to store this pointer off for later use, using a TStringList so that it can be linked to a name.

procedure TfrmTopicICDLinker.btnEditSectionClick(Sender: TObject);
var
  frmGUIEditFMFile: TfrmGUIEditFMFile;
  i : integer;
  Data, IEN : string;
  GridInfo : TGridInfo; //owned elsewhere
  Handler : THandleTableCellEdit;
  HandlerPtr : Pointer;

begin
  i := lbSection.ItemIndex; if i < 0 then exit;
  Data := lbSection.Items[i];
  IEN := piece(Data,'^',4);

  frmGUIEditFMFile := TfrmGUIEditFMFile.Create(Self);
  try
    frmGUIEditFMFile.SetGridsToShow([integer(tsgAdvanced)]);
    frmGUIEditFMFile.PrepForm('22753', IEN+',', IntToStr(User.DUZ));
    GridInfo := frmGUIEditFMFile.GridInfo(tsgAdvanced);
    GridInfo.IdentifierCode := 'DO SUBRECID^TMGTIUT3(DIC,Y,+$GET(DIFILE))';
    Handler := HandlePtrEdit;
    HandlerPtr := Handler;  //<---------- !! Error here !!
    GridInfo.CustomPtrFieldEditors.AddObject('80', HandlerPtr); 
    frmGUIEditFMFile.ShowModal;
  finally
    frmGUIEditFMFile.Free;
  end;
end;

The problem is that when I store the pointer, the compiler thinks I want to call the function pointer instead, and complains that there are "Not enough actual parameters". I have tried several ways of casting it to a standard pointer, but no luck.

How to I force the compiler to treat the function pointer like any other pointer, and not to try to evaluate it?

Is there a better way to solve this problem? I am using Delphi 2006 (!), so I can’t use template/typed lists that I am aware of.

Thanks in advance.

>Solution :

You don’t need the Handler variable at all. You can assign the address of your function directly to your HandlerPtr variable.

To get that address, you can use the @ operator:

HandlerPtr := @HandlePtrEdit;

Alternatively, the Addr() intrinsic:

HandlerPtr := Addr(HandlePtrEdit);

Leave a Reply