?
Solved

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

Posted on 2001-09-04
6
Medium Priority
?
241 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
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…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…
This tutorial will teach you the special effect of super speed similar to the fictional character Wally West aka "The Flash" After Shake : http://www.videocopilot.net/presets/after_shake/ All lightning effects with instructions : http://www.mediaf…
Suggested Courses
Course of the Month12 days, 11 hours left to enroll

777 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