How to gaing access to a Property of an object in a TObjectList.

How to gaing access to a Property of an object in a TObjectList.

This is a question about Fast-Script, from fast Reports company.


I have the next classes into a File:

TConfigCompProps = class(TObject)
FCD_COMPONENT :string;
FDS_COMPONENT :string;
FQTY_QUANTITY :Double;
FFRONT :Integer;
FDEPTH :Integer;
FTHICK :Integer;
FCD_COLOR :string;
FPACKAGE :Integer;
FPROGRAM_ID :String;
FPRI_UNIT :Double;
FEXPLANATION :string;
published
property CD_COMPONENT :string read FCD_COMPONENT write FCD_COMPONENT;
property DS_COMPONENT :string read FDS_COMPONENT write FDS_COMPONENT;
property QTY_QUANTITY :Double read FQTY_QUANTITY write FQTY_QUANTITY;
property FRONT :Integer read FFRONT write FFRONT ;
property DEPTH :Integer read FDEPTH write FDEPTH ;
property THICK :Integer read FTHICK write FTHICK ;
property CD_COLOR :string read FCD_COLOR write FCD_COLOR ;
property PACKAGE :Integer read FPACKAGE write FPACKAGE ;
property PROGRAM_ID :String read FPROGRAM_ID write FPROGRAM_ID ;
property PRI_UNIT :Double read FPRI_UNIT write FPRI_UNIT ;
property EXPLANATION :string read FEXPLANATION write FEXPLANATION ;
end;

TConfigCompList = class(TObjectList)
private
protected
procedure SetComponent(Index :Integer; Item: TConfigCompProps);
function GetComponent(Index :Integer):TConfigCompProps;
public
property Components[Index :Integer]:TConfigCompProps read GetComponent write SetComponent; default;
published
constructor Create; overload;
function Add(Obj :TConfigCompProps):Integer; overload;
procedure Insert(Index :Integer; Obj :TConfigCompProps);
end;


In the Object from which I create the script I have the next declaration:

FComponents :TConfigCompList;
property Component :TConf......

I have a method in which I feed with data this structure:

procedure TConfigCompOrm.FeedScriptObject;
var Component :TConfigCompOrm;
ConfigComp :TConfigCompProps;
begin
FComponents := TConfigCompList.Create;
for Component in FConfiguration do begin
ConfigComp := TConfigCompProps.Create;
ConfigComp.CD_COMPONENT := Component.CD_COMPONENT.AsString ;
ConfigComp.DS_COMPONENT := Component.DS_COMPONENT.AsString ;
ConfigComp.QTY_QUANTITY := Component.QTY_QUANTITY.AsExtended;
ConfigComp.FRONT := Component.FRONT.AsInteger ;
ConfigComp.DEPTH := Component.DEPTH.AsInteger ;
ConfigComp.THICK := Component.THICK.AsInteger ;
ConfigComp.CD_COLOR := Component.CD_COLOR.AsString ;
ConfigComp.PACKAGE := Component.PACKAGE.AsInteger ;
ConfigComp.PROGRAM_ID := Component.PROGRAM_ID.AsString ;
ConfigComp.PRI_UNIT := Component.PRI_UNIT.AsExtended ;
ConfigComp.EXPLANATION := Component.EXPLANATION.AsString ;
FComponents.Add(Component);
end;
end;



Before execute the Script I have the next adds....

FeedScriptObject;
{ add new class inherited from TObject }
with Script.AddClass(TConfigCompProps, 'TObject') do begin
{ Don't has public methods }
end;

with Script.AddClass(TConfigCompList, 'TObjectList') do begin
{ add public methods }
AddProperty('Count', 'Integer', GetProp, nil);
{ Add Index property Components[Index :Integer]:TConfigCompProps }
AddIndexProperty ('Components', 'Integer', 'TConfigCompProps', CallMethod);
AddDefaultProperty('Components', 'Integer', 'TConfigCompProps', CallMethod);
end;

Script.AddObject('Components', FComponents);

and for the CallMethod I have the next :

if MethodName = 'COMPONENTS.GET' then Result := Integer(TConfigCompList(Instance).Components[Params[0]])
else if MethodName = 'COMPONENTS.SET' then TStrings(Instance).Objects[Params[0]] := TConfigCompList(Integer(Params[1]))
else if MethodName = 'STRINGS.GET' then Result := TStrings(Instance).Strings[Params[0]]
else if MethodName = 'STRINGS.SET' then TStrings(Instance).Strings[Params[0]] := Params[1];

The first Line is the important one.

I use the next SCRIPT :

begin
ResultValue := Components[0].CD_COLOR;
end.

but when interpret this script I get and exception: "Invalid Class typecast".

Any one can help me about how should I declare the CallMethod for gain access to the Properties of the TConfigCompProps class?

Thank you in advance!

Comments

  1. Randy Sill

    This is for use with Fast-Script.
    I need to make use of external data, inside the scripts.

    Because Fast-Script don't have Generics, I use a work around: I convert the list "FConfiguration" whose members are of type TConfigCompOrm into a new list: FComponents (or Components in the property name) whose members are of type TConfigCompProps (descendandt of TObject).

    The problem is into the method "CallMethod". I'm treating of use the proposal of Fast-Scripts documentation, and in the point showed I can't gain access to the properties of the simple class TConfigCompProps.

    This is the complete declartion of the method CallMethod:

    function TConfigCompOrm.CallMethod(Instance :TObject; ClassType :TClass; const MethodName :string; var Params :Variant):Variant;
    begin
    Result := 0;
    if MethodName = 'COMPONENTS.GET' then Result := Integer(TConfigCompList(Instance).Components[Params[0]])
    else if MethodName = 'COMPONENTS.SET' then TConfigCompProps(Instance).Components[Params[0]] := TConfigCompList(Integer(Params[1]))
    else if MethodName = 'STRINGS.GET' then Result := TStrings(Instance).Strings[Params[0]]
    else if MethodName = 'STRINGS.SET' then TStrings(Instance).Strings[Params[0]] := Params[1];
    end;

    the first "if" is where I need to gain access to, by example, the property CD_COLOR.

    Thanks.

    ReplyDelete
  2. The problem remains. The use of TConfigCompList(Instance) or (Instance as TConfigCompList) is not relevant in this context.

    I'm sure that the returned type is TConfigCompList, why make, to the system, use time performing a type checking when is not necessary?

    ReplyDelete
  3. Randy Sill
    The invalid typecasting becomes by the last word in the script. CD_COLOR.

    This is the problem. I'm having access to the TConfigCompProps inside the TConfigCompList, but I'm not having access to his individual properties.

    The access to this properties must be inside the script. ;)

    ReplyDelete
  4. Randy Sill

    Yes! Components property is in the published section. The problem is the type of this property.

    Finally I've surrendered to this problem and I've adopted a workaround for solve this requirement. Instead of pass the data to a more single class and after, pass this class to the script, I opted by create a set of properties and methods, of basic types, that I "published" in my class and put in knowledge of the script.

    This really works better. It's more code, but runs in Fast-script and in PascalScript (remobjects) too.

    A question.

    I've tried, to this task, this too script tools and I've see the TMSScripter tool.

    I have the next opinion.

    - Fast-Script is very basic, but at least works. The documentation is poor, very poor.
    - PascalScript is very good, and works, but the documentation is more poor. And the support is null.
    - I've do not used TMSScripter, because my experience with TMS Software is bad, very bud. But seems that have the same problem as pascalscript. A very bad documentation and a very bad support service.

    Also, PascalScript and TMSScripter has the same problem with the included IDE. Don't works with FMX, and this is mandatory for my application.

    If you have used these tools, agree you my opinión? And, do you know another Script Tools for Delphi that I can integrate without much complication? The inside script language is not important, may be anyone.

    Thanks for all Randy!

    ReplyDelete

Post a Comment