fpc/rtl/objpas/typinfo.pp
michael 23ad0ae1ec + Removed HASINTF and VER1_0 defines
git-svn-id: trunk@239 -
2005-06-07 20:30:03 +00:00

1548 lines
48 KiB
ObjectPascal

{
This file is part of the Free Pascal run time library.
Copyright (c) 1999-2000 by Florian Klaempfl
member of the Free Pascal development team
See the file COPYING.FPC, included in this distribution,
for details about the copyright.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**********************************************************************}
{ This unit provides the same Functionality as the TypInfo Unit }
{ of Delphi }
unit typinfo;
interface
{$MODE objfpc}
{$h+}
uses SysUtils;
// temporary types:
type
{$ifndef HASVARIANT}
Variant = Pointer;
{$endif}
{$MINENUMSIZE 1 this saves a lot of memory }
// if you change one of the following enumeration types
// you have also to change the compiler in an appropriate way !
TTypeKind = (tkUnknown,tkInteger,tkChar,tkEnumeration,
tkFloat,tkSet,tkMethod,tkSString,tkLString,tkAString,
tkWString,tkVariant,tkArray,tkRecord,tkInterface,
tkClass,tkObject,tkWChar,tkBool,tkInt64,tkQWord,
tkDynArray,tkInterfaceRaw);
TOrdType = (otSByte,otUByte,otSWord,otUWord,otSLong,otULong);
TFloatType = (ftSingle,ftDouble,ftExtended,ftComp,ftCurr);
TMethodKind = (mkProcedure,mkFunction,mkConstructor,mkDestructor,
mkClassProcedure, mkClassFunction);
TParamFlags = set of (pfVar,pfConst,pfArray,pfAddress,pfReference,pfOut);
TIntfFlag = (ifHasGuid,ifDispInterface,ifDispatch);
TIntfFlags = set of TIntfFlag;
TIntfFlagsBase = set of TIntfFlag;
{$MINENUMSIZE DEFAULT}
const
ptField = 0;
ptStatic = 1;
ptVirtual = 2;
ptConst = 3;
tkString = tkSString;
type
TTypeKinds = set of TTypeKind;
{$PACKRECORDS 1}
TTypeInfo = record
Kind : TTypeKind;
Name : ShortString;
// here the type data follows as TTypeData record
end;
PTypeInfo = ^TTypeInfo;
PPTypeInfo = ^PTypeInfo;
{$PACKRECORDS C}
PTypeData = ^TTypeData;
TTypeData =
{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
packed
{$endif FPC_REQUIRES_PROPER_ALIGNMENT}
record
case TTypeKind of
tkUnKnown,tkLString,tkWString,tkAString,tkVariant:
();
tkInteger,tkChar,tkEnumeration,tkWChar:
(OrdType : TOrdType;
case TTypeKind of
tkInteger,tkChar,tkEnumeration,tkBool,tkWChar : (
MinValue,MaxValue : Longint;
case TTypeKind of
tkEnumeration:
(
BaseType : PTypeInfo;
NameList : ShortString)
);
tkSet:
(CompType : PTypeInfo)
);
tkFloat:
(FloatType : TFloatType);
tkSString:
(MaxLength : Byte);
tkClass:
(ClassType : TClass;
ParentInfo : PTypeInfo;
PropCount : SmallInt;
UnitName : ShortString
// here the properties follow as array of TPropInfo
);
tkMethod:
(MethodKind : TMethodKind;
ParamCount : Byte;
ParamList : array[0..1023] of Char
{in reality ParamList is a array[1..ParamCount] of:
record
Flags : TParamFlags;
ParamName : ShortString;
TypeName : ShortString;
end;
followed by
ResultType : ShortString}
);
tkInt64:
(MinInt64Value, MaxInt64Value: Int64);
tkQWord:
(MinQWordValue, MaxQWordValue: QWord);
tkInterface,
tkInterfaceRaw:
(
IntfParent: PPTypeInfo;
IID: PGUID;
IIDStr: ShortString;
IntfUnit: ShortString;
);
end;
// unsed, just for completeness
TPropData =
{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
packed
{$endif FPC_REQUIRES_PROPER_ALIGNMENT}
record
PropCount : Word;
PropList : record _alignmentdummy : ptrint; end;
end;
{$PACKRECORDS 1}
PPropInfo = ^TPropInfo;
TPropInfo = packed record
PropType : PTypeInfo;
GetProc : Pointer;
SetProc : Pointer;
StoredProc : Pointer;
Index : Integer;
Default : Longint;
NameIndex : SmallInt;
// contains the type of the Get/Set/Storedproc, see also ptxxx
// bit 0..1 GetProc
// 2..3 SetProc
// 4..5 StoredProc
// 6 : true, constant index property
PropProcs : Byte;
Name : ShortString;
end;
TProcInfoProc = Procedure(PropInfo : PPropInfo) of object;
PPropList = ^TPropList;
TPropList = array[0..65535] of PPropInfo;
const
tkAny = [Low(TTypeKind)..High(TTypeKind)];
tkMethods = [tkMethod];
tkProperties = tkAny-tkMethods-[tkUnknown];
// general property handling
Function GetTypeData(TypeInfo : PTypeInfo) : PTypeData;
Function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string) : PPropInfo;
Function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string; AKinds : TTypeKinds) : PPropInfo;
Function GetPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds) : PPropInfo;
Function GetPropInfo(Instance: TObject; const PropName: string): PPropInfo;
Function GetPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds) : PPropInfo;
Function GetPropInfo(AClass: TClass; const PropName: string): PPropInfo;
Function FindPropInfo(Instance: TObject; const PropName: string): PPropInfo;
Function FindPropInfo(AClass:TClass;const PropName: string): PPropInfo;
Procedure GetPropInfos(TypeInfo : PTypeInfo;PropList : PPropList);
Function GetPropList(TypeInfo : PTypeInfo;TypeKinds : TTypeKinds; PropList : PPropList;Sorted : boolean = true):longint;
Function GetPropList(TypeInfo: PTypeInfo; out PropList: PPropList): SizeInt;
// Property information routines.
Function IsStoredProp(Instance: TObject;PropInfo : PPropInfo) : Boolean;
Function IsStoredProp(Instance: TObject; const PropName: string): Boolean;
Function IsPublishedProp(Instance: TObject; const PropName: string): Boolean;
Function IsPublishedProp(AClass: TClass; const PropName: string): Boolean;
Function PropType(Instance: TObject; const PropName: string): TTypeKind;
Function PropType(AClass: TClass; const PropName: string): TTypeKind;
Function PropIsType(Instance: TObject; const PropName: string; TypeKind: TTypeKind): Boolean;
Function PropIsType(AClass: TClass; const PropName: string; TypeKind: TTypeKind): Boolean;
// subroutines to read/write properties
Function GetOrdProp(Instance: TObject; PropInfo : PPropInfo) : Int64;
Function GetOrdProp(Instance: TObject; const PropName: string): Int64;
Procedure SetOrdProp(Instance: TObject; PropInfo : PPropInfo; Value : Int64);
Procedure SetOrdProp(Instance: TObject; const PropName: string; Value: Int64);
Function GetEnumProp(Instance: TObject; const PropName: string): string;
Function GetEnumProp(Instance: TObject; const PropInfo: PPropInfo): string;
Procedure SetEnumProp(Instance: TObject; const PropName: string;const Value: string);
Procedure SetEnumProp(Instance: TObject; const PropInfo: PPropInfo;const Value: string);
Function GetSetProp(Instance: TObject; const PropName: string): string;
Function GetSetProp(Instance: TObject; const PropName: string; Brackets: Boolean): string;
Function GetSetProp(Instance: TObject; const PropInfo: PPropInfo; Brackets: Boolean): string;
Procedure SetSetProp(Instance: TObject; const PropName: string; const Value: string);
Procedure SetSetProp(Instance: TObject; const PropInfo: PPropInfo; const Value: string);
Function GetStrProp(Instance: TObject; PropInfo : PPropInfo) : Ansistring;
Function GetStrProp(Instance: TObject; const PropName: string): string;
Procedure SetStrProp(Instance: TObject; const PropName: string; const Value: AnsiString);
Procedure SetStrProp(Instance: TObject; PropInfo : PPropInfo; const Value : Ansistring);
{$ifdef HASWIDESTRING}
Function GetWideStrProp(Instance: TObject; PropInfo: PPropInfo): WideString;
Function GetWideStrProp(Instance: TObject; const PropName: string): WideString;
Procedure SetWideStrProp(Instance: TObject; const PropName: string; const Value: WideString);
Procedure SetWideStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: WideString);
{$endif HASWIDESTRING}
Function GetFloatProp(Instance: TObject; PropInfo : PPropInfo) : Extended;
Function GetFloatProp(Instance: TObject; const PropName: string): Extended;
Procedure SetFloatProp(Instance: TObject; const PropName: string; Value: Extended);
Procedure SetFloatProp(Instance: TObject; PropInfo : PPropInfo; Value : Extended);
Function GetObjectProp(Instance: TObject; const PropName: string): TObject;
Function GetObjectProp(Instance: TObject; const PropName: string; MinClass: TClass): TObject;
Function GetObjectProp(Instance: TObject; PropInfo: PPropInfo): TObject;
Function GetObjectProp(Instance: TObject; PropInfo: PPropInfo; MinClass: TClass): TObject;
Procedure SetObjectProp(Instance: TObject; const PropName: string; Value: TObject);
Procedure SetObjectProp(Instance: TObject; PropInfo: PPropInfo; Value: TObject);
Function GetObjectPropClass(Instance: TObject; const PropName: string): TClass;
Function GetMethodProp(Instance: TObject; PropInfo: PPropInfo) : TMethod;
Function GetMethodProp(Instance: TObject; const PropName: string): TMethod;
Procedure SetMethodProp(Instance: TObject; PropInfo: PPropInfo; const Value : TMethod);
Procedure SetMethodProp(Instance: TObject; const PropName: string; const Value: TMethod);
Function GetInt64Prop(Instance: TObject; PropInfo: PPropInfo): Int64;
Function GetInt64Prop(Instance: TObject; const PropName: string): Int64;
Procedure SetInt64Prop(Instance: TObject; PropInfo: PPropInfo; const Value: Int64);
Procedure SetInt64Prop(Instance: TObject; const PropName: string; const Value: Int64);
Function GetPropValue(Instance: TObject; const PropName: string): Variant;
Function GetPropValue(Instance: TObject; const PropName: string; PreferStrings: Boolean): Variant;
Procedure SetPropValue(Instance: TObject; const PropName: string; const Value: Variant);
Function GetVariantProp(Instance: TObject; PropInfo : PPropInfo): Variant;
Function GetVariantProp(Instance: TObject; const PropName: string): Variant;
Procedure SetVariantProp(Instance: TObject; const PropName: string; const Value: Variant);
Procedure SetVariantProp(Instance: TObject; PropInfo : PPropInfo; const Value: Variant);
// Auxiliary routines, which may be useful
Function GetEnumName(TypeInfo : PTypeInfo;Value : Integer) : string;
Function GetEnumValue(TypeInfo : PTypeInfo;const Name : string) : Integer;
function SetToString(PropInfo: PPropInfo; Value: Integer; Brackets: Boolean) : String;
function SetToString(PropInfo: PPropInfo; Value: Integer) : String;
function StringToSet(PropInfo: PPropInfo; const Value: string): Integer;
const
BooleanIdents: array[Boolean] of String = ('False', 'True');
DotSep: String = '.';
Type
EPropertyError = Class(Exception);
TGetPropValue = Function (Instance: TObject; const PropName: string; PreferStrings: Boolean) : Variant;
TSetPropValue = Procedure (Instance: TObject; const PropName: string; const Value: Variant);
TGetVariantProp = Function (Instance: TObject; PropInfo : PPropInfo): Variant;
TSetVariantProp = Procedure (Instance: TObject; PropInfo : PPropInfo; const Value: Variant);
Const
OnGetPropValue : TGetPropValue = Nil;
OnSetPropValue : TSetPropValue = Nil;
OnGetVariantprop : TGetVariantProp = Nil;
OnSetVariantprop : TSetVariantProp = Nil;
Implementation
uses rtlconsts;
type
PMethod = ^TMethod;
{ ---------------------------------------------------------------------
Auxiliary methods
---------------------------------------------------------------------}
function aligntoptr(p : pointer) : pointer;
begin
{$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
if (ptrint(p) mod sizeof(ptrint))<>0 then
inc(ptrint(p),sizeof(ptrint)-ptrint(p) mod sizeof(ptrint));
{$endif FPC_REQUIRES_PROPER_ALIGNMENT}
result:=p;
end;
Function GetEnumName(TypeInfo : PTypeInfo;Value : Integer) : string;
Var PS : PShortString;
PT : PTypeData;
begin
PT:=GetTypeData(TypeInfo);
// ^.BaseType);
// If PT^.MinValue<0 then Value:=Ord(Value<>0); {map to 0/1}
PS:=@PT^.NameList;
While Value>0 Do
begin
PS:=PShortString(pointer(PS)+PByte(PS)^+1);
Dec(Value);
end;
Result:=PS^;
end;
Function GetEnumValue(TypeInfo : PTypeInfo;const Name : string) : Integer;
Var PS : PShortString;
PT : PTypeData;
Count : longint;
begin
If Length(Name)=0 then
exit(-1);
PT:=GetTypeData(TypeInfo);
Count:=0;
Result:=-1;
PS:=@PT^.NameList;
While (Result=-1) and (PByte(PS)^<>0) do
begin
If CompareText(PS^, Name) = 0 then
Result:=Count;
PS:=PShortString(pointer(PS)+PByte(PS)^+1);
Inc(Count);
end;
end;
Function SetToString(PropInfo: PPropInfo; Value: Integer; Brackets: Boolean) : String;
Var
I : Integer;
PTI : PTypeInfo;
begin
PTI:=GetTypeData(PropInfo^.PropType)^.CompType;
Result:='';
For I:=0 to SizeOf(Integer)*8-1 do
begin
if ((Value and 1)<>0) then
begin
If Result='' then
Result:=GetEnumName(PTI,i)
else
Result:=Result+','+GetEnumName(PTI,I);
end;
Value:=Value shr 1;
end;
if Brackets then
Result:='['+Result+']';
end;
Function SetToString(PropInfo: PPropInfo; Value: Integer) : String;
begin
Result:=SetToString(PropInfo,Value,False);
end;
Const
SetDelim = ['[',']',',',' '];
Function GetNextElement(Var S : String) : String;
Var
J : Integer;
begin
J:=1;
Result:='';
If Length(S)>0 then
begin
While (J<=Length(S)) and Not (S[j] in SetDelim) do
Inc(j);
Result:=Copy(S,1,j-1);
Delete(S,1,j);
end;
end;
Function StringToSet(PropInfo: PPropInfo; const Value: string): Integer;
Var
S,T : String;
I : Integer;
PTI : PTypeInfo;
begin
Result:=0;
PTI:=GetTypeData(PropInfo^.PropType)^.Comptype;
S:=Value;
I:=1;
If Length(S)>0 then
begin
While (I<=Length(S)) and (S[i] in SetDelim) do
Inc(I);
Delete(S,1,i-1);
end;
While (S<>'') do
begin
T:=GetNextElement(S);
if T<>'' then
begin
I:=GetEnumValue(PTI,T);
if (I<0) then
raise EPropertyError.CreateFmt(SErrUnknownEnumValue, [T]);
Result:=Result or (1 shl i);
end;
end;
end;
Function GetTypeData(TypeInfo : PTypeInfo) : PTypeData;
begin
GetTypeData:=PTypeData(aligntoptr(PTypeData(pointer(TypeInfo)+2+PByte(pointer(TypeInfo)+1)^)));
end;
{ ---------------------------------------------------------------------
Basic Type information functions.
---------------------------------------------------------------------}
Function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string) : PPropInfo;
var
hp : PTypeData;
i : longint;
p : string;
pd : ^TPropData;
begin
P:=UpCase(PropName);
while Assigned(TypeInfo) do
begin
// skip the name
hp:=GetTypeData(Typeinfo);
// the class info rtti the property rtti follows immediatly
pd:=aligntoptr(pointer(pointer(@hp^.UnitName)+Length(hp^.UnitName)+1));
Result:=@pd^.PropList;
for i:=1 to pd^.PropCount do
begin
// found a property of that name ?
if Upcase(Result^.Name)=P then
exit;
// skip to next property
Result:=PPropInfo(aligntoptr(pointer(@Result^.Name)+byte(Result^.Name[0])+1));
end;
// parent class
Typeinfo:=hp^.ParentInfo;
end;
Result:=Nil;
end;
Function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string; Akinds : TTypeKinds) : PPropInfo;
begin
Result:=GetPropInfo(TypeInfo,PropName);
If (Akinds<>[]) then
If (Result<>Nil) then
If Not (Result^.PropType^.Kind in AKinds) then
Result:=Nil;
end;
Function GetPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds) : PPropInfo;
begin
Result:=GetPropInfo(PTypeInfo(AClass.ClassInfo),PropName,AKinds);
end;
Function GetPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds) : PPropInfo;
begin
Result:=GetPropInfo(Instance.ClassType,PropName,AKinds);
end;
Function GetPropInfo(Instance: TObject; const PropName: string): PPropInfo;
begin
Result:=GetPropInfo(Instance,PropName,[]);
end;
Function GetPropInfo(AClass: TClass; const PropName: string): PPropInfo;
begin
Result:=GetPropInfo(AClass,PropName,[]);
end;
Function FindPropInfo(Instance: TObject; const PropName: string): PPropInfo;
begin
result:=GetPropInfo(Instance, PropName);
if Result=nil then
Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
end;
Function FindPropInfo(AClass:TClass;const PropName: string): PPropInfo;
begin
result:=GetPropInfo(AClass,PropName);
if result=nil then
Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
end;
Function IsStoredProp(Instance : TObject;PropInfo : PPropInfo) : Boolean;
type
TBooleanFunc=function:boolean of object;
var
AMethod : TMethod;
begin
case (PropInfo^.PropProcs shr 4) and 3 of
ptfield:
Result:=PBoolean(Pointer(Instance)+Longint(PropInfo^.StoredProc))^;
ptconst:
Result:=LongBool(PropInfo^.StoredProc);
ptstatic,
ptvirtual:
begin
if (PropInfo^.PropProcs shr 4) and 3=ptstatic then
AMethod.Code:=PropInfo^.StoredProc
else
AMethod.Code:=ppointer(Pointer(Instance.ClassType)+Longint(PropInfo^.StoredProc))^;
AMethod.Data:=Instance;
Result:=TBooleanFunc(AMethod)();
end;
end;
end;
Procedure GetPropInfos(TypeInfo : PTypeInfo;PropList : PPropList);
{
Store Pointers to property information in the list pointed
to by proplist. PRopList must contain enough space to hold ALL
properties.
}
Var
TD : PTypeData;
TP : PPropInfo;
Count : Longint;
begin
TD:=GetTypeData(TypeInfo);
// Get this objects TOTAL published properties count
TP:=aligntoptr(PPropInfo(aligntoptr((@TD^.UnitName+Length(TD^.UnitName)+1))));
Count:=PWord(TP)^;
// Now point TP to first propinfo record.
Inc(Pointer(TP),SizeOF(Word));
tp:=aligntoptr(tp);
While Count>0 do
begin
PropList^[0]:=TP;
Inc(Pointer(PropList),SizeOf(Pointer));
// Point to TP next propinfo record.
// Located at Name[Length(Name)+1] !
TP:=aligntoptr(PPropInfo(pointer(@TP^.Name)+PByte(@TP^.Name)^+1));
Dec(Count);
end;
// recursive call for parent info.
If TD^.Parentinfo<>Nil then
GetPropInfos (TD^.ParentInfo,PropList);
end;
Procedure InsertProp (PL : PProplist;PI : PPropInfo; Count : longint);
Var
I : Longint;
begin
I:=0;
While (I<Count) and (PI^.Name>PL^[I]^.Name) do
Inc(I);
If I<Count then
Move(PL^[I], PL^[I+1], (Count - I) * SizeOf(Pointer));
PL^[I]:=PI;
end;
Procedure InsertPropnosort (PL : PProplist;PI : PPropInfo; Count : longint);
begin
PL^[Count]:=PI;
end;
Type TInsertProp = Procedure (PL : PProplist;PI : PPropInfo; Count : longint);
//Const InsertProps : array[false..boolean] of TInsertProp = (InsertPropNoSort,InsertProp);
Function GetPropList(TypeInfo : PTypeInfo;TypeKinds : TTypeKinds; PropList : PPropList;Sorted : boolean = true):longint;
{
Store Pointers to property information OF A CERTAIN KIND in the list pointed
to by proplist. PRopList must contain enough space to hold ALL
properties.
}
Var
TempList : PPropList;
PropInfo : PPropinfo;
I,Count : longint;
DoInsertProp : TInsertProp;
begin
if sorted then
DoInsertProp:=@InsertProp
else
DoInsertProp:=@InsertPropnosort;
Result:=0;
Count:=GetTypeData(TypeInfo)^.Propcount;
If Count>0 then
begin
GetMem(TempList,Count*SizeOf(Pointer));
Try
GetPropInfos(TypeInfo,TempList);
For I:=0 to Count-1 do
begin
PropInfo:=TempList^[i];
If PropInfo^.PropType^.Kind in TypeKinds then
begin
If (PropList<>Nil) then
DoInsertProp(PropList,PropInfo,Result);
Inc(Result);
end;
end;
finally
FreeMem(TempList,Count*SizeOf(Pointer));
end;
end;
end;
Function GetPropList(TypeInfo: PTypeInfo; out PropList: PPropList): SizeInt;
begin
result:=GetTypeData(TypeInfo)^.Propcount;
if result>0 then
begin
getmem(PropList,result*sizeof(pointer));
GetPropInfos(TypeInfo,PropList);
end;
end;
{ ---------------------------------------------------------------------
Property access functions
---------------------------------------------------------------------}
{ ---------------------------------------------------------------------
Ordinal properties
---------------------------------------------------------------------}
Function GetOrdProp(Instance : TObject;PropInfo : PPropInfo) : Int64;
type
TGetInt64ProcIndex=function(index:longint):Int64 of object;
TGetInt64Proc=function():Int64 of object;
TGetIntegerProcIndex=function(index:longint):longint of object;
TGetIntegerProc=function:longint of object;
TGetWordProcIndex=function(index:longint):word of object;
TGetWordProc=function:word of object;
TGetByteProcIndex=function(index:longint):Byte of object;
TGetByteProc=function:Byte of object;
var
TypeInfo: PTypeInfo;
AMethod : TMethod;
DataSize: Integer;
OrdType: TOrdType;
Signed: Boolean;
begin
Result:=0;
TypeInfo := PropInfo^.PropType;
Signed := false;
DataSize := 4;
case TypeInfo^.Kind of
tkChar, tkBool:
DataSize:=1;
tkWChar:
DataSize:=2;
tkEnumeration,
tkInteger:
begin
OrdType:=GetTypeData(TypeInfo)^.OrdType;
case OrdType of
otSByte,otUByte: DataSize := 1;
otSWord,otUWord: DataSize := 2;
end;
Signed := OrdType in [otSByte,otSWord,otSLong];
end;
tkInt64 :
begin
DataSize:=8;
Signed:=true;
end;
tkQword :
begin
DataSize:=8;
Signed:=false;
end;
end;
case (PropInfo^.PropProcs) and 3 of
ptfield:
if Signed then begin
case DataSize of
1: Result:=PShortInt(Pointer(Instance)+Ptrint(PropInfo^.GetProc))^;
2: Result:=PSmallInt(Pointer(Instance)+Ptrint(PropInfo^.GetProc))^;
4: Result:=PLongint(Pointer(Instance)+Ptrint(PropInfo^.GetProc))^;
8: Result:=PInt64(Pointer(Instance)+Ptrint(PropInfo^.GetProc))^;
end;
end else begin
case DataSize of
1: Result:=PByte(Pointer(Instance)+Ptrint(PropInfo^.GetProc))^;
2: Result:=PWord(Pointer(Instance)+Ptrint(PropInfo^.GetProc))^;
4: Result:=PLongint(Pointer(Instance)+Ptrint(PropInfo^.GetProc))^;
8: Result:=PInt64(Pointer(Instance)+Ptrint(PropInfo^.GetProc))^;
end;
end;
ptstatic,
ptvirtual :
begin
if (PropInfo^.PropProcs and 3)=ptStatic then
AMethod.Code:=PropInfo^.GetProc
else
AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Ptrint(PropInfo^.GetProc))^;
AMethod.Data:=Instance;
if ((PropInfo^.PropProcs shr 6) and 1)<>0 then begin
case DataSize of
1: Result:=TGetByteProcIndex(AMethod)(PropInfo^.Index);
2: Result:=TGetWordProcIndex(AMethod)(PropInfo^.Index);
4: Result:=TGetIntegerProcIndex(AMethod)(PropInfo^.Index);
8: result:=TGetInt64ProcIndex(AMethod)(PropInfo^.Index)
end;
end else begin
case DataSize of
1: Result:=TGetByteProc(AMethod)();
2: Result:=TGetWordProc(AMethod)();
4: Result:=TGetIntegerProc(AMethod)();
8: result:=TGetInt64Proc(AMethod)();
end;
end;
if Signed then begin
case DataSize of
1: Result:=ShortInt(Result);
2: Result:=SmallInt(Result);
end;
end;
end;
end;
end;
Procedure SetOrdProp(Instance : TObject;PropInfo : PPropInfo;Value : Int64);
type
TSetInt64ProcIndex=procedure(index:longint;i:Int64) of object;
TSetInt64Proc=procedure(i:Int64) of object;
TSetIntegerProcIndex=procedure(index,i:longint) of object;
TSetIntegerProc=procedure(i:longint) of object;
var
DataSize: Integer;
AMethod : TMethod;
begin
if PropInfo^.PropType^.Kind in [tkInt64,tkQword] then
DataSize := 8
else
DataSize := 4;
if PropInfo^.PropType^.Kind <> tkClass then
begin
{ cut off unnecessary stuff }
case GetTypeData(PropInfo^.PropType)^.OrdType of
otSWord,otUWord:
begin
Value:=Value and $ffff;
DataSize := 2;
end;
otSByte,otUByte:
begin
Value:=Value and $ff;
DataSize := 1;
end;
end;
end;
case (PropInfo^.PropProcs shr 2) and 3 of
ptfield:
case DataSize of
1: PByte(Pointer(Instance)+Ptrint(PropInfo^.SetProc))^:=Byte(Value);
2: PWord(Pointer(Instance)+Ptrint(PropInfo^.SetProc))^:=Word(Value);
4:PLongint(Pointer(Instance)+Ptrint(PropInfo^.SetProc))^:=Longint(Value);
8: PInt64(Pointer(Instance)+Ptrint(PropInfo^.SetProc))^:=Value;
end;
ptstatic,
ptvirtual :
begin
if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
AMethod.Code:=PropInfo^.SetProc
else
AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Ptrint(PropInfo^.SetProc))^;
AMethod.Data:=Instance;
if datasize=8 then
begin
if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
TSetInt64ProcIndex(AMethod)(PropInfo^.Index,Value)
else
TSetInt64Proc(AMethod)(Value);
end
else
begin
if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
TSetIntegerProcIndex(AMethod)(PropInfo^.Index,Value)
else
TSetIntegerProc(AMethod)(Value);
end;
end;
end;
end;
Function GetOrdProp(Instance: TObject; const PropName: string): Int64;
begin
Result:=GetOrdProp(Instance,FindPropInfo(Instance,PropName));
end;
Procedure SetOrdProp(Instance: TObject; const PropName: string; Value: Int64);
begin
SetOrdProp(Instance,FindPropInfo(Instance,PropName),Value);
end;
Function GetEnumProp(Instance: TObject; Const PropInfo: PPropInfo): string;
begin
Result:=GetEnumName(PropInfo^.PropType, GetOrdProp(Instance, PropInfo));
end;
Function GetEnumProp(Instance: TObject; const PropName: string): string;
begin
Result:=GetEnumProp(Instance,FindPropInfo(Instance,PropName));
end;
Procedure SetEnumProp(Instance: TObject; const PropName: string; const Value: string);
begin
SetEnumProp(Instance,FindPropInfo(Instance,PropName),Value);
end;
Procedure SetEnumProp(Instance: TObject; Const PropInfo : PPropInfo; const Value: string);
Var
PV : Longint;
begin
If PropInfo<>Nil then
begin
PV:=GetEnumValue(PropInfo^.PropType, Value);
if (PV<0) then
raise EPropertyError.CreateFmt(SErrUnknownEnumValue, [Value]);
SetOrdProp(Instance, PropInfo,PV);
end;
end;
{ ---------------------------------------------------------------------
Int64 wrappers
---------------------------------------------------------------------}
Function GetInt64Prop(Instance: TObject; PropInfo: PPropInfo): Int64;
begin
Result:=GetOrdProp(Instance,PropInfo);
end;
procedure SetInt64Prop(Instance: TObject; PropInfo: PPropInfo; const Value: Int64);
begin
SetOrdProp(Instance,PropInfo,Value);
end;
Function GetInt64Prop(Instance: TObject; const PropName: string): Int64;
begin
Result:=GetInt64Prop(Instance,FindPropInfo(Instance,PropName));
end;
Procedure SetInt64Prop(Instance: TObject; const PropName: string; const Value: Int64);
begin
SetInt64Prop(Instance,FindPropInfo(Instance,PropName),Value);
end;
{ ---------------------------------------------------------------------
Set properties
---------------------------------------------------------------------}
Function GetSetProp(Instance: TObject; const PropName: string): string;
begin
Result:=GetSetProp(Instance,PropName,False);
end;
Function GetSetProp(Instance: TObject; const PropName: string; Brackets: Boolean): string;
begin
Result:=GetSetProp(Instance,FindPropInfo(Instance,PropName),Brackets);
end;
Function GetSetProp(Instance: TObject; const PropInfo: PPropInfo; Brackets: Boolean): string;
begin
Result:=SetToString(PropInfo,GetOrdProp(Instance,PropInfo),Brackets);
end;
Procedure SetSetProp(Instance: TObject; const PropName: string; const Value: string);
begin
SetSetProp(Instance,FindPropInfo(Instance,PropName),Value);
end;
Procedure SetSetProp(Instance: TObject; const PropInfo: PPropInfo; const Value: string);
begin
SetOrdProp(Instance,PropInfo,StringToSet(PropInfo,Value));
end;
{ ---------------------------------------------------------------------
Object properties
---------------------------------------------------------------------}
Function GetObjectProp(Instance: TObject; const PropName: string): TObject;
begin
Result:=GetObjectProp(Instance,PropName,Nil);
end;
Function GetObjectProp(Instance: TObject; const PropName: string; MinClass: TClass): TObject;
begin
Result:=GetObjectProp(Instance,FindPropInfo(Instance,PropName),MinClass);
end;
Function GetObjectProp(Instance: TObject; PropInfo : PPropInfo): TObject;
begin
Result:=GetObjectProp(Instance,PropInfo,Nil);
end;
Function GetObjectProp(Instance: TObject; PropInfo : PPropInfo; MinClass: TClass): TObject;
begin
{$ifdef cpu64}
Result:=TObject(GetInt64Prop(Instance,PropInfo));
{$else cpu64}
Result:=TObject(PtrInt(GetOrdProp(Instance,PropInfo)));
{$endif cpu64}
If (MinClass<>Nil) and (Result<>Nil) Then
If Not Result.InheritsFrom(MinClass) then
Result:=Nil;
end;
Procedure SetObjectProp(Instance: TObject; const PropName: string; Value: TObject);
begin
SetObjectProp(Instance,FindPropInfo(Instance,PropName),Value);
end;
Procedure SetObjectProp(Instance: TObject; PropInfo : PPropInfo; Value: TObject);
begin
{$ifdef cpu64}
SetInt64Prop(Instance,PropInfo,Int64(Value));
{$else cpu64}
SetOrdProp(Instance,PropInfo,Integer(Value));
{$endif cpu64}
end;
Function GetObjectPropClass(Instance: TObject; const PropName: string): TClass;
begin
Result:=GetTypeData(FindPropInfo(Instance,PropName)^.PropType)^.ClassType;
end;
{ ---------------------------------------------------------------------
String properties
---------------------------------------------------------------------}
Function GetStrProp(Instance: TObject; PropInfo: PPropInfo): AnsiString;
type
TGetShortStrProcIndex=function(index:longint):ShortString of object;
TGetShortStrProc=function():ShortString of object;
TGetAnsiStrProcIndex=function(index:longint):AnsiString of object;
TGetAnsiStrProc=function():AnsiString of object;
var
AMethod : TMethod;
begin
Result:='';
case Propinfo^.PropType^.Kind of
{$ifdef HASWIDESTRING}
tkWString:
Result:=GetWideStrProp(Instance,PropInfo);
{$endif HASWIDESTRING}
tkSString:
begin
case (PropInfo^.PropProcs) and 3 of
ptField:
Result := PShortString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
ptstatic,
ptvirtual :
begin
if (PropInfo^.PropProcs and 3)=ptStatic then
AMethod.Code:=PropInfo^.GetProc
else
AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Ptrint(PropInfo^.GetProc))^;
AMethod.Data:=Instance;
if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
Result:=TGetShortStrProcIndex(AMethod)(PropInfo^.Index)
else
Result:=TGetShortStrProc(AMethod)();
end;
end;
end;
tkAString:
begin
case (PropInfo^.PropProcs) and 3 of
ptField:
Result := PAnsiString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
ptstatic,
ptvirtual :
begin
if (PropInfo^.PropProcs and 3)=ptStatic then
AMethod.Code:=PropInfo^.GetProc
else
AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Ptrint(PropInfo^.GetProc))^;
AMethod.Data:=Instance;
if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
Result:=TGetAnsiStrProcIndex(AMethod)(PropInfo^.Index)
else
Result:=TGetAnsiStrProc(AMethod)();
end;
end;
end;
end;
end;
Procedure SetStrProp(Instance : TObject;PropInfo : PPropInfo; const Value : AnsiString);
type
TSetShortStrProcIndex=procedure(index:longint;const s:ShortString) of object;
TSetShortStrProc=procedure(const s:ShortString) of object;
TSetAnsiStrProcIndex=procedure(index:longint;s:AnsiString) of object;
TSetAnsiStrProc=procedure(s:AnsiString) of object;
var
AMethod : TMethod;
begin
case Propinfo^.PropType^.Kind of
{$ifdef HASWIDESTRING}
tkWString:
SetWideStrProp(Instance,PropInfo,Value);
{$endif HASWIDESTRING}
tkSString:
begin
case (PropInfo^.PropProcs shr 2) and 3 of
ptField:
PShortString(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
ptstatic,
ptvirtual :
begin
if (PropInfo^.PropProcs and 3)=ptStatic then
AMethod.Code:=PropInfo^.SetProc
else
AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Ptrint(PropInfo^.SetProc))^;
AMethod.Data:=Instance;
if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
TSetShortStrProcIndex(AMethod)(PropInfo^.Index,Value)
else
TSetShortStrProc(AMethod)(Value);
end;
end;
end;
tkAString:
begin
case (PropInfo^.PropProcs shr 2) and 3 of
ptField:
PAnsiString(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
ptstatic,
ptvirtual :
begin
if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
AMethod.Code:=PropInfo^.SetProc
else
AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Ptrint(PropInfo^.SetProc))^;
AMethod.Data:=Instance;
if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
TSetAnsiStrProcIndex(AMethod)(PropInfo^.Index,Value)
else
TSetAnsiStrProc(AMethod)(Value);
end;
end;
end;
end;
end;
Function GetStrProp(Instance: TObject; const PropName: string): string;
begin
Result:=GetStrProp(Instance,FindPropInfo(Instance,PropName));
end;
Procedure SetStrProp(Instance: TObject; const PropName: string; const Value: AnsiString);
begin
SetStrProp(Instance,FindPropInfo(Instance,PropName),Value);
end;
{$ifdef HASWIDESTRING}
Function GetWideStrProp(Instance: TObject; const PropName: string): WideString;
begin
Result:=GetWideStrProp(Instance, FindPropInfo(Instance, PropName));
end;
procedure SetWideStrProp(Instance: TObject; const PropName: string; const Value: WideString);
begin
SetWideStrProp(Instance,FindPropInfo(Instance,PropName),Value);
end;
Function GetWideStrProp(Instance: TObject; PropInfo: PPropInfo): WideString;
type
TGetWideStrProcIndex=function(index:longint):WideString of object;
TGetWideStrProc=function():WideString of object;
var
AMethod : TMethod;
begin
Result:='';
case Propinfo^.PropType^.Kind of
tkSString,tkAString:
Result:=GetStrProp(Instance,PropInfo);
tkWString:
begin
case (PropInfo^.PropProcs) and 3 of
ptField:
Result := PWideString(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
ptstatic,
ptvirtual :
begin
if (PropInfo^.PropProcs and 3)=ptStatic then
AMethod.Code:=PropInfo^.GetProc
else
AMethod.Code:=PPointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
AMethod.Data:=Instance;
if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
Result:=TGetWideStrProcIndex(AMethod)(PropInfo^.Index)
else
Result:=TGetWideStrProc(AMethod)();
end;
end;
end;
end;
end;
Procedure SetWideStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: WideString);
type
TSetWideStrProcIndex=procedure(index:longint;s:WideString) of object;
TSetWideStrProc=procedure(s:WideString) of object;
var
AMethod : TMethod;
begin
case Propinfo^.PropType^.Kind of
tkSString,tkAString:
SetStrProp(Instance,PropInfo,Value);
tkWString:
begin
case (PropInfo^.PropProcs shr 2) and 3 of
ptField:
PWideString(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
ptstatic,
ptvirtual :
begin
if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
AMethod.Code:=PropInfo^.SetProc
else
AMethod.Code:=PPointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
AMethod.Data:=Instance;
if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
TSetWideStrProcIndex(AMethod)(PropInfo^.Index,Value)
else
TSetWideStrProc(AMethod)(Value);
end;
end;
end;
end;
end;
{$endif HASWIDESTRING}
{ ---------------------------------------------------------------------
Float properties
---------------------------------------------------------------------}
function GetFloatProp(Instance : TObject;PropInfo : PPropInfo) : Extended;
type
TGetExtendedProc = function:Extended of object;
TGetExtendedProcIndex = function(Index: integer): Extended of object;
TGetDoubleProc = function:Double of object;
TGetDoubleProcIndex = function(Index: integer): Double of object;
TGetSingleProc = function:Single of object;
TGetSingleProcIndex = function(Index: integer):Single of object;
{$ifdef HASCURRENCY}
TGetCurrencyProc = function : Currency of object;
TGetCurrencyProcIndex = function(Index: integer) : Currency of object;
{$endif HASCURRENCY}
var
AMethod : TMethod;
begin
Result:=0.0;
case PropInfo^.PropProcs and 3 of
ptField:
Case GetTypeData(PropInfo^.PropType)^.FloatType of
ftSingle:
Result:=PSingle(Pointer(Instance)+Ptrint(PropInfo^.GetProc))^;
ftDouble:
Result:=PDouble(Pointer(Instance)+Ptrint(PropInfo^.GetProc))^;
ftExtended:
Result:=PExtended(Pointer(Instance)+Ptrint(PropInfo^.GetProc))^;
ftcomp:
Result:=PComp(Pointer(Instance)+Ptrint(PropInfo^.GetProc))^;
{$ifdef HASCURRENCY}
ftcurr:
Result:=PCurrency(Pointer(Instance)+Ptrint(PropInfo^.GetProc))^;
{$endif HASCURRENCY}
end;
ptStatic,
ptVirtual:
begin
if (PropInfo^.PropProcs and 3)=ptStatic then
AMethod.Code:=PropInfo^.GetProc
else
AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Ptrint(PropInfo^.GetProc))^;
AMethod.Data:=Instance;
Case GetTypeData(PropInfo^.PropType)^.FloatType of
ftSingle:
if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
Result:=TGetSingleProc(AMethod)()
else
Result:=TGetSingleProcIndex(AMethod)(PropInfo^.Index);
ftDouble:
if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
Result:=TGetDoubleProc(AMethod)()
else
Result:=TGetDoubleProcIndex(AMethod)(PropInfo^.Index);
ftExtended:
if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
Result:=TGetExtendedProc(AMethod)()
else
Result:=TGetExtendedProcIndex(AMethod)(PropInfo^.Index);
{$ifdef HASCURRENCY}
ftCurr:
if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
Result:=TGetCurrencyProc(AMethod)()
else
Result:=TGetCurrencyProcIndex(AMethod)(PropInfo^.Index);
{$endif HASCURRENCY}
end;
end;
end;
end;
Procedure SetFloatProp(Instance : TObject;PropInfo : PPropInfo; Value : Extended);
type
TSetExtendedProc = procedure(const AValue: Extended) of object;
TSetExtendedProcIndex = procedure(Index: integer; const AValue: Extended) of object;
TSetDoubleProc = procedure(const AValue: Double) of object;
TSetDoubleProcIndex = procedure(Index: integer; const AValue: Double) of object;
TSetSingleProc = procedure(const AValue: Single) of object;
TSetSingleProcIndex = procedure(Index: integer; const AValue: Single) of object;
{$ifdef HASCURRENCY}
TSetCurrencyProc = procedure(const AValue: Currency) of object;
TSetCurrencyProcIndex = procedure(Index: integer; const AValue: Currency) of object;
{$endif HASCURRENCY}
Var
AMethod : TMethod;
begin
case (PropInfo^.PropProcs shr 2) and 3 of
ptfield:
Case GetTypeData(PropInfo^.PropType)^.FloatType of
ftSingle:
PSingle(Pointer(Instance)+Ptrint(PropInfo^.SetProc))^:=Value;
ftDouble:
PDouble(Pointer(Instance)+Ptrint(PropInfo^.SetProc))^:=Value;
ftExtended:
PExtended(Pointer(Instance)+Ptrint(PropInfo^.SetProc))^:=Value;
{$ifdef FPC_COMP_IS_INT64}
ftComp:
PComp(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=trunc(Value);
{$else FPC_COMP_IS_INT64}
ftComp:
PComp(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
{$endif FPC_COMP_IS_INT64}
{$ifdef HASCURRENCY}
ftCurr:
PCurrency(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
{$endif HASCURRENCY}
end;
ptStatic,
ptVirtual:
begin
if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
AMethod.Code:=PropInfo^.SetProc
else
AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Ptrint(PropInfo^.SetProc))^;
AMethod.Data:=Instance;
Case GetTypeData(PropInfo^.PropType)^.FloatType of
ftSingle:
if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
TSetSingleProc(AMethod)(Value)
else
TSetSingleProcIndex(AMethod)(PropInfo^.Index,Value);
ftDouble:
if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
TSetDoubleProc(AMethod)(Value)
else
TSetDoubleProcIndex(AMethod)(PropInfo^.Index,Value);
ftExtended:
if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
TSetExtendedProc(AMethod)(Value)
else
TSetExtendedProcIndex(AMethod)(PropInfo^.Index,Value);
{$ifdef HASCURRENCY}
ftCurr:
if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
TSetCurrencyProc(AMethod)(Value)
else
TSetCurrencyProcIndex(AMethod)(PropInfo^.Index,Value);
{$endif HASCURRENCY}
end;
end;
end;
end;
function GetFloatProp(Instance: TObject; const PropName: string): Extended;
begin
Result:=GetFloatProp(Instance,FindPropInfo(Instance,PropName))
end;
Procedure SetFloatProp(Instance: TObject; const PropName: string; Value: Extended);
begin
SetFloatProp(Instance,FindPropInfo(Instance,PropName),Value);
end;
{ ---------------------------------------------------------------------
Method properties
---------------------------------------------------------------------}
Function GetMethodProp(Instance : TObject;PropInfo : PPropInfo) : TMethod;
type
TGetMethodProcIndex=function(Index: Longint): TMethod of object;
TGetMethodProc=function(): TMethod of object;
var
value: PMethod;
AMethod : TMethod;
begin
Result.Code:=nil;
Result.Data:=nil;
case (PropInfo^.PropProcs) and 3 of
ptfield:
begin
Value:=PMethod(Pointer(Instance)+Ptrint(PropInfo^.GetProc));
if Value<>nil then
Result:=Value^;
end;
ptstatic,
ptvirtual :
begin
if (PropInfo^.PropProcs and 3)=ptStatic then
AMethod.Code:=PropInfo^.GetProc
else
AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Ptrint(PropInfo^.GetProc))^;
AMethod.Data:=Instance;
if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
Result:=TGetMethodProcIndex(AMethod)(PropInfo^.Index)
else
Result:=TGetMethodProc(AMethod)();
end;
end;
end;
Procedure SetMethodProp(Instance : TObject;PropInfo : PPropInfo; const Value : TMethod);
type
TSetMethodProcIndex=procedure(index:longint;p:PMethod) of object;
TSetMethodProc=procedure(p:PMethod) of object;
var
AMethod : TMethod;
begin
case (PropInfo^.PropProcs shr 2) and 3 of
ptfield:
PMethod(Pointer(Instance)+Ptrint(PropInfo^.SetProc))^ := Value;
ptstatic,
ptvirtual :
begin
if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
AMethod.Code:=PropInfo^.SetProc
else
AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Ptrint(PropInfo^.SetProc))^;
AMethod.Data:=Instance;
if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
TSetMethodProcIndex(AMethod)(PropInfo^.Index,@Value)
else
TSetMethodProc(AMethod)(@Value);
end;
end;
end;
Function GetMethodProp(Instance: TObject; const PropName: string): TMethod;
begin
Result:=GetMethodProp(Instance,FindPropInfo(Instance,PropName));
end;
Procedure SetMethodProp(Instance: TObject; const PropName: string; const Value: TMethod);
begin
SetMethodProp(Instance,FindPropInfo(Instance,PropName),Value);
end;
{ ---------------------------------------------------------------------
Variant properties
---------------------------------------------------------------------}
Procedure CheckVariantEvent(P : Pointer);
begin
If (P=Nil) then
Raise Exception.Create(SErrNoVariantSupport);
end;
Function GetVariantProp(Instance : TObject;PropInfo : PPropInfo): Variant;
begin
CheckVariantEvent(Pointer(OnGetVariantProp));
Result:=OnGetVariantProp(Instance,PropInfo);
end;
Procedure SetVariantProp(Instance : TObject;PropInfo : PPropInfo; const Value: Variant);
begin
CheckVariantEvent(Pointer(OnSetVariantProp));
OnSetVariantProp(Instance,PropInfo,Value);
end;
Function GetVariantProp(Instance: TObject; const PropName: string): Variant;
begin
Result:=GetVariantProp(Instance,FindPropInfo(Instance,PropName));
end;
Procedure SetVariantProp(Instance: TObject; const PropName: string; const Value: Variant);
begin
SetVariantprop(instance,FindpropInfo(Instance,PropName),Value);
end;
{ ---------------------------------------------------------------------
All properties through variant.
---------------------------------------------------------------------}
Function GetPropValue(Instance: TObject; const PropName: string): Variant;
begin
Result:=GetPropValue(Instance,PropName,True);
end;
Function GetPropValue(Instance: TObject; const PropName: string; PreferStrings: Boolean): Variant;
begin
CheckVariantEvent(Pointer(OnGetPropValue));
Result:=OnGetPropValue(Instance,PropName,PreferStrings)
end;
Procedure SetPropValue(Instance: TObject; const PropName: string; const Value: Variant);
begin
CheckVariantEvent(Pointer(OnSetPropValue));
OnSetPropValue(Instance,PropName,Value);
end;
{ ---------------------------------------------------------------------
Easy access methods that appeared in Delphi 5
---------------------------------------------------------------------}
Function IsPublishedProp(Instance: TObject; const PropName: string): Boolean;
begin
Result:=GetPropInfo(Instance,PropName)<>Nil;
end;
Function IsPublishedProp(AClass: TClass; const PropName: string): Boolean;
begin
Result:=GetPropInfo(AClass,PropName)<>Nil;
end;
Function PropIsType(Instance: TObject; const PropName: string; TypeKind: TTypeKind): Boolean;
begin
Result:=FindPropInfo(Instance,PropName)^.PropType^.Kind=TypeKind
end;
Function PropIsType(AClass: TClass; const PropName: string; TypeKind: TTypeKind): Boolean;
begin
Result:=PropType(AClass,PropName)=TypeKind
end;
Function PropType(Instance: TObject; const PropName: string): TTypeKind;
begin
Result:=FindPropInfo(Instance,PropName)^.PropType^.Kind;
end;
Function PropType(AClass: TClass; const PropName: string): TTypeKind;
begin
Result:=FindPropInfo(AClass,PropName)^.PropType^.Kind;
end;
Function IsStoredProp(Instance: TObject; const PropName: string): Boolean;
begin
Result:=IsStoredProp(instance,FindPropInfo(Instance,PropName));
end;
end.