?
Solved

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

Posted on 2001-09-04
6
Medium Priority
?
251 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 450 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
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
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

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

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

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…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Despite its rising prevalence in the business world, "the cloud" is still misunderstood. Some companies still believe common misconceptions about lack of security in cloud solutions and many misuses of cloud storage options still occur every day. …
When cloud platforms entered the scene, users and companies jumped on board to take advantage of the many benefits, like the ability to work and connect with company information from various locations. What many didn't foresee was the increased risk…
Suggested Courses
Course of the Month15 days, 12 hours left to enroll

850 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