Solved

Executing an objects' procedure/function using the run-time information...

Posted on 2001-09-04
6
226 Views
Last Modified: 2010-04-06
The problem is I need to access the 'SetRange' and 'CancelRange' procedures of a TTable (amongst other things)... * BUT * it not only needs to work for a TTable but also a TffTable (FlashFiler) and a TADSTable (Advantage) [and possibly any other Table type that has the procedures declared].
So I am using the table as a TDataSet.
As the procedures aren't declared until the TTable class I can't type cast back and I can't typecast forward as the unit cannot not be specific to any type of Table, ie. not using conditional compilations or Uses or "If oTable is TffTable then"...etc

Example Code fragment:
procedure SetRangeOnTable(oTable: TDataSet);
begin
  // set IndexName via run-time property information
  SetStrProp(oTable,'IndexName','ixCode');

  // Execute SetRange() via run-time information
end;
0
Comment
Question by:djadja
  • 4
  • 2
6 Comments
 
LVL 10

Accepted Solution

by:
Jacco earned 150 total points
ID: 6452749
Here is a way to do it.

You have to register every class you want to do it with:

procedure TForm1.Button1Click(Sender: TObject);
begin
  RegisterSetRange(AdsTable2, AdsTable2.SetRange);
  CallSetRange(AdsTable1, [200135], [200135]);
end;

Regards Jacco

unit SetRange;

interface

uses
  Db;

type
  TDataSetClass = class of TDataSet;
  TSetRangeProc = procedure (const StartValues, EndValues: array of const) of object;


procedure RegisterSetRange(aDataSet: TDataSet; aSetRangeProc: TSetRangeProc);
procedure CallSetRange(aDataSet: TDataSet; const StartValues, EndValues: array of const);

implementation

uses
  Classes, SysUtils;

var
  DataSetList: TStringList;

procedure RegisterSetRange(aDataSet: TDataSet; aSetRangeProc: TSetRangeProc);
begin
  if not Assigned(DataSetList) then
  begin
    DataSetList := TStringList.Create;
    DataSetList.Duplicates := dupError;
  end;
  DataSetList.AddObject(aDataSet.ClassName, @aSetRangeProc);
end;

procedure CallSetRange(aDataSet: TDataSet; const StartValues, EndValues: array of const);
var
  lMethod: TMethod;
  liIndex: Integer;
begin
  liIndex := DataSetList.IndexOf(aDataSet.ClassName);
  if liIndex >= 0 then
  begin
    lMethod.Code := DataSetList.Objects[liIndex];
    lMethod.Data := aDataSet;
    TSetRangeProc(lMethod)(StartValues, EndValues);
  end else
    raise Exception.Create('You have not registered '+aDataSet.ClassName+' for SetRange');
end;

initialization
finalization
  DataSetList.Free;
end.
0
 

Author Comment

by:djadja
ID: 6453501
Bit of a fag for my fellow developers who use my object having to do this...isn't their any other way of doing this?

I've already tried various things like GetMethodProp, oDataSet.MethodAddress('EmptyTable')
but it just gives me AV's or nil's for procedures/functions/events.
0
 
LVL 10

Expert Comment

by:Jacco
ID: 6453972
I don't think there is another way. (Only rewriting the VCL sources...).

- You only have to register the classes once per class.
- You could include ifdef structures to take care of the registering (maybe inside include files)

Regards Jacco
0
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 10

Expert Comment

by:Jacco
ID: 6457871
This solution does fit your requirments:

- it works with any TDataSet descendant with a procedure that matches the prototype:

    procedure (const StartValues, EndValues: array of const) of object;

- the unit is not dependant (not using any DbTables, AdsData etc) on the 3rd party units.

- there is no if or case (only a registration lookup)

Regards Jacco
0
 
LVL 10

Expert Comment

by:Jacco
ID: 6470863
Are you still here?
0
 

Author Comment

by:djadja
ID: 6470961
Whoops yeah - sorry been working on something else.

Yeah - looks like I'll have to lump it and do it this way
:(

Points R yours!
0

Featured Post

Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Delphi - replicating a form 8 81
Mobile Keyboard covers the display of the TMemo 3 96
Downloading email attachments 2 79
Firemonkey BASS_Init into a thread 17 30
This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…
In an interesting question (https://www.experts-exchange.com/questions/29008360/) here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…

856 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question