Solved

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

Posted on 2001-09-04
6
227 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 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
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

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

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…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Nobody understands Phishing better than an anti-spam company. That’s why we are providing Phishing Awareness Training to our customers. According to a report by Verizon, only 3% of targeted users report malicious emails to management. With compan…
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…

726 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