Solved

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

Posted on 2001-09-04
6
222 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
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
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

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
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…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

747 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

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now