123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854 |
- {
- 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}
- {$inline on}
- {$h+}
- uses SysUtils;
- // temporary types:
- type
- {$MINENUMSIZE 1 this saves a lot of memory }
- {$ifdef FPC_RTTI_PACKSET1}
- { for Delphi compatibility }
- {$packset 1}
- {$endif}
- // 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,tkProcVar,tkUString,tkUChar);
- TOrdType = (otSByte,otUByte,otSWord,otUWord,otSLong,otULong);
- {$ifndef FPUNONE}
- TFloatType = (ftSingle,ftDouble,ftExtended,ftComp,ftCurr);
- {$endif}
- TMethodKind = (mkProcedure,mkFunction,mkConstructor,mkDestructor,
- mkClassProcedure, mkClassFunction);
- TParamFlag = (pfVar,pfConst,pfArray,pfAddress,pfReference,pfOut);
- TParamFlags = set of TParamFlag;
- TIntfFlag = (ifHasGuid,ifDispInterface,ifDispatch,ifHasStrGUID);
- 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;
- ShortStringBase = string[255];
- {$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,tkUString:
- ();
- tkInteger,tkChar,tkEnumeration,tkWChar,tkSet:
- (OrdType : TOrdType;
- case TTypeKind of
- tkInteger,tkChar,tkEnumeration,tkBool,tkWChar : (
- MinValue,MaxValue : Longint;
- case TTypeKind of
- tkEnumeration:
- (
- BaseType : PTypeInfo;
- NameList : ShortString)
- );
- tkSet:
- (CompType : PTypeInfo)
- );
- {$ifndef FPUNONE}
- tkFloat:
- (FloatType : TFloatType);
- {$endif}
- 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:
- (
- IntfParent: PTypeInfo;
- IntfFlags : TIntfFlagsBase;
- GUID: TGUID;
- IntfUnit: ShortString;
- );
- tkInterfaceRaw:
- (
- RawIntfParent: PTypeInfo;
- RawIntfFlags : TIntfFlagsBase;
- IID: TGUID;
- RawIntfUnit: ShortString;
- IIDStr: ShortString;
- );
- tkDynArray:
- (
- elSize : PtrUInt;
- elType2 : PPTypeInfo;
- varType : Longint;
- elType : PPTypeInfo;
- DynUnitName: ShortStringBase
- );
- 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): PPropInfo;
- Function GetPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds): PPropInfo;
- Function GetPropInfo(AClass: TClass; const PropName: string): PPropInfo;
- Function GetPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds): PPropInfo;
- Function FindPropInfo(Instance: TObject; const PropName: string): PPropInfo;
- Function FindPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds): PPropInfo;
- Function FindPropInfo(AClass: TClass; const PropName: string): PPropInfo;
- Function FindPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds): 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;
- function GetPropList(AClass: TClass; out PropList: PPropList): Integer;
- function GetPropList(Instance: TObject; out PropList: PPropList): Integer;
- // 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);
- 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);
- Function GetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo): UnicodeString;
- Function GetUnicodeStrProp(Instance: TObject; const PropName: string): UnicodeString;
- Procedure SetUnicodeStrProp(Instance: TObject; const PropName: string; const Value: UnicodeString);
- Procedure SetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: UnicodeString);
- {$ifndef FPUNONE}
- 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);
- {$endif}
- 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 GetObjectPropClass(AClass: TClass; 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);
- function GetInterfaceProp(Instance: TObject; const PropName: string): IInterface;
- function GetInterfaceProp(Instance: TObject; PropInfo: PPropInfo): IInterface;
- procedure SetInterfaceProp(Instance: TObject; const PropName: string; const Value: IInterface);
- procedure SetInterfaceProp(Instance: TObject; PropInfo: PPropInfo; const Value: IInterface);
- // Auxiliary routines, which may be useful
- Function GetEnumName(TypeInfo : PTypeInfo;Value : Integer) : string;
- Function GetEnumValue(TypeInfo : PTypeInfo;const Name : string) : Integer;
- function GetEnumNameCount(enum1: PTypeInfo): SizeInt;
- function SetToString(TypeInfo: PTypeInfo; Value: Integer; Brackets: Boolean) : String;
- function SetToString(PropInfo: PPropInfo; Value: Integer; Brackets: Boolean) : String;
- function SetToString(PropInfo: PPropInfo; Value: Integer) : String;
- function StringToSet(PropInfo: PPropInfo; const Value: string): Integer;
- function StringToSet(TypeInfo: PTypeInfo; 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);
- EPropertyConvertError = class(Exception); // Not used (yet), but defined for compatibility.
- 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;inline;
- begin
- {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
- result:=align(p,sizeof(p));
- {$else FPC_REQUIRES_PROPER_ALIGNMENT}
- result:=p;
- {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
- end;
- Function GetEnumName(TypeInfo : PTypeInfo;Value : Integer) : string;
- Var PS : PShortString;
- PT : PTypeData;
- begin
- PT:=GetTypeData(TypeInfo);
- if TypeInfo^.Kind=tkBool then
- begin
- case Value of
- 0,1:
- Result:=BooleanIdents[Boolean(Value)];
- else
- Result:='';
- end;
- end
- else
- begin
- PS:=@PT^.NameList;
- While Value>0 Do
- begin
- PS:=PShortString(pointer(PS)+PByte(PS)^+1);
- Dec(Value);
- end;
- Result:=PS^;
- end;
- end;
- Function GetEnumValue(TypeInfo : PTypeInfo;const Name : string) : Integer;
- Var PS : PShortString;
- PT : PTypeData;
- Count : longint;
- sName: shortstring;
- begin
- If Length(Name)=0 then
- exit(-1);
- sName := Name;
- PT:=GetTypeData(TypeInfo);
- Count:=0;
- Result:=-1;
-
- if TypeInfo^.Kind=tkBool then
- begin
- If CompareText(BooleanIdents[false],Name)=0 then
- result:=0
- else if CompareText(BooleanIdents[true],Name)=0 then
- result:=1;
- end
- else
- begin
-
- PS:=@PT^.NameList;
- While (Result=-1) and (PByte(PS)^<>0) do
- begin
- If ShortCompareText(PS^, sName) = 0 then
- Result:=Count;
- PS:=PShortString(pointer(PS)+PByte(PS)^+1);
- Inc(Count);
- end;
- end;
- end;
- function GetEnumNameCount(enum1: PTypeInfo): SizeInt;
- var
- PS: PShortString;
- PT: PTypeData;
- Count: SizeInt;
- begin
- PT:=GetTypeData(enum1);
- if enum1^.Kind=tkBool then
- Result:=2
- else
- begin
- Count:=0;
- Result:=0;
-
- PS:=@PT^.NameList;
- While (PByte(PS)^<>0) do
- begin
- PS:=PShortString(pointer(PS)+PByte(PS)^+1);
- Inc(Count);
- end;
-
- Result := Count;
- end;
- end;
- Function SetToString(PropInfo: PPropInfo; Value: Integer; Brackets: Boolean) : String;
- begin
- Result:=SetToString(PropInfo^.PropType,Value,Brackets);
- end;
- Function SetToString(TypeInfo: PTypeInfo; Value: Integer; Brackets: Boolean) : String;
- type
- tsetarr = bitpacked array[0..31] of 0..1;
- Var
- I : Integer;
- PTI : PTypeInfo;
- begin
- {$if defined(FPC_BIG_ENDIAN)}
- { On big endian systems, set element 0 is in the most significant bit,
- and the same goes for the elements of bitpacked arrays there. }
- case GetTypeData(TypeInfo)^.OrdType of
- otSByte,otUByte: Value:=Value shl 24;
- otSWord,otUWord: Value:=Value shl 16;
- end;
- {$endif}
- PTI:=GetTypeData(TypeInfo)^.CompType;
- Result:='';
- For I:=0 to SizeOf(Integer)*8-1 do
- begin
- if (tsetarr(Value)[i]<>0) then
- begin
- If Result='' then
- Result:=GetEnumName(PTI,i)
- else
- Result:=Result+','+GetEnumName(PTI,I);
- end;
- 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;
- begin
- Result:=StringToSet(PropInfo^.PropType,Value);
- end;
- Function StringToSet(TypeInfo: PTypeInfo; const Value: string): Integer;
- Var
- S,T : String;
- I : Integer;
- PTI : PTypeInfo;
- begin
- Result:=0;
- PTI:=GetTypeData(TypeInfo)^.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 : shortstring;
- pd : ^TPropData;
- begin
- P:=PropName; // avoid Ansi<->short conversion in a loop
- 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:=PPropInfo(@pd^.PropList);
- for i:=1 to pd^.PropCount do
- begin
- // found a property of that name ?
- if ShortCompareText(Result^.Name, P) = 0 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(Instance: TObject; const PropName: string; AKinds: TTypeKinds): PPropInfo;
- begin
- result:=GetPropInfo(Instance, PropName, AKinds);
- 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 FindPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds): PPropInfo;
- begin
- result:=GetPropInfo(AClass, PropName, AKinds);
- if result=nil then
- Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
- end;
- Function IsStoredProp(Instance : TObject;PropInfo : PPropInfo) : Boolean;
- type
- TBooleanIndexFunc=function(Index:integer):boolean of object;
- TBooleanFunc=function:boolean of object;
- var
- AMethod : TMethod;
- begin
- case (PropInfo^.PropProcs shr 4) and 3 of
- ptfield:
- Result:=PBoolean(Pointer(Instance)+PtrUInt(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)+PtrUInt(PropInfo^.StoredProc))^;
- AMethod.Data:=Instance;
- if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
- Result:=TBooleanIndexFunc(AMethod)(PropInfo^.Index)
- else
- 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
- // Get this objects TOTAL published properties count
- TD:=GetTypeData(TypeInfo);
- // Clear list
- FillChar(PropList^,TD^.PropCount*sizeof(Pointer),0);
- repeat
- TD:=GetTypeData(TypeInfo);
- // published properties count for this object
- TP:=aligntoptr(PPropInfo(aligntoptr((Pointer(@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
- // Don't overwrite properties with the same name
- if PropList^[TP^.NameIndex]=nil then
- PropList^[TP^.NameIndex]:=TP;
- // 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;
- TypeInfo:=TD^.Parentinfo;
- until TypeInfo=nil;
- 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
- else
- PropList:=Nil;
- end;
- function GetPropList(AClass: TClass; out PropList: PPropList): Integer;
- begin
- Result := GetPropList(PTypeInfo(AClass.ClassInfo), PropList);
- end;
- function GetPropList(Instance: TObject; out PropList: PPropList): Integer;
- begin
- Result := GetPropList(Instance.ClassType, PropList);
- 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
- {$ifdef cpu64}
- tkInterface,
- tkInterfaceRaw,
- tkDynArray,
- tkClass:
- DataSize:=8;
- {$endif cpu64}
- tkChar, tkBool:
- DataSize:=1;
- tkWChar:
- DataSize:=2;
- tkSet,
- 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)+PtrUInt(PropInfo^.GetProc))^;
- 2: Result:=PSmallInt(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
- 4: Result:=PLongint(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
- 8: Result:=PInt64(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
- end;
- end else begin
- case DataSize of
- 1: Result:=PByte(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
- 2: Result:=PWord(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
- 4: Result:=PLongint(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
- 8: Result:=PInt64(Pointer(Instance)+PtrUInt(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)+PtrUInt(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
- { why do we have to handle classes here, see also below? (FK) }
- {$ifdef cpu64}
- ,tkInterface
- ,tkInterfaceRaw
- ,tkDynArray
- ,tkClass
- {$endif cpu64}
- ] then
- DataSize := 8
- else
- DataSize := 4;
- if not(PropInfo^.PropType^.Kind in [tkInt64,tkQword,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)+PtrUInt(PropInfo^.SetProc))^:=Byte(Value);
- 2: PWord(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Word(Value);
- 4: PLongint(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Longint(Value);
- 8: PInt64(Pointer(Instance)+PtrUInt(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)+PtrUInt(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,[tkClass])^.PropType)^.ClassType;
- end;
- Function GetObjectPropClass(AClass: TClass; const PropName: string): TClass;
- begin
- Result:=GetTypeData(FindPropInfo(AClass,PropName,[tkClass])^.PropType)^.ClassType;
- end;
- { ---------------------------------------------------------------------
- Interface wrapprers
- ---------------------------------------------------------------------}
- function GetInterfaceProp(Instance: TObject; const PropName: string): IInterface;
- begin
- Result:=GetInterfaceProp(Instance,FindPropInfo(Instance,PropName));
- end;
- function GetInterfaceProp(Instance: TObject; PropInfo: PPropInfo): IInterface;
- begin
- {$ifdef cpu64}
- Result:=IInterface(GetInt64Prop(Instance,PropInfo));
- {$else cpu64}
- Result:=IInterface(PtrInt(GetOrdProp(Instance,PropInfo)));
- {$endif cpu64}
- end;
- procedure SetInterfaceProp(Instance: TObject; const PropName: string; const Value: IInterface);
- begin
- SetInterfaceProp(Instance,FindPropInfo(Instance,PropName),Value);
- end;
- procedure SetInterfaceProp(Instance: TObject; PropInfo: PPropInfo; const Value: IInterface);
- type
- TSetIntfStrProcIndex=procedure(index:longint;const i:IInterface) of object;
- TSetIntfStrProc=procedure(i:IInterface) of object;
- var
- AMethod : TMethod;
- begin
- case Propinfo^.PropType^.Kind of
- tkInterface:
- begin
- case (PropInfo^.PropProcs shr 2) and 3 of
- ptField:
- PInterface(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
- TSetIntfStrProcIndex(AMethod)(PropInfo^.Index,Value)
- else
- TSetIntfStrProc(AMethod)(Value);
- end;
- end;
- end;
- end;
- 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
- tkWString:
- Result:=GetWideStrProp(Instance,PropInfo);
- tkUString :
- Result := GetUnicodeStrProp(Instance,PropInfo);
- 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)+PtrUInt(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)+PtrUInt(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
- tkWString:
- SetWideStrProp(Instance,PropInfo,Value);
- tkUString:
- SetUnicodeStrProp(Instance,PropInfo,Value);
- tkSString:
- begin
- case (PropInfo^.PropProcs shr 2) and 3 of
- ptField:
- PShortString(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)+PtrUInt(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)+PtrUInt(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;
- 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);
- tkUString :
- Result := GetUnicodeStrProp(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);
- tkUString:
- SetUnicodeStrProp(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;
- Function GetUnicodeStrProp(Instance: TObject; const PropName: string): UnicodeString;
- begin
- Result:=GetUnicodeStrProp(Instance, FindPropInfo(Instance, PropName));
- end;
- procedure SetUnicodeStrProp(Instance: TObject; const PropName: string; const Value: UnicodeString);
- begin
- SetUnicodeStrProp(Instance,FindPropInfo(Instance,PropName),Value);
- end;
- Function GetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo): UnicodeString;
- type
- TGetUnicodeStrProcIndex=function(index:longint):UnicodeString of object;
- TGetUnicodeStrProc=function():UnicodeString of object;
- var
- AMethod : TMethod;
- begin
- Result:='';
- case Propinfo^.PropType^.Kind of
- tkSString,tkAString:
- Result:=GetStrProp(Instance,PropInfo);
- tkWString:
- Result:=GetWideStrProp(Instance,PropInfo);
- tkUString:
- begin
- case (PropInfo^.PropProcs) and 3 of
- ptField:
- Result := PUnicodeString(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:=TGetUnicodeStrProcIndex(AMethod)(PropInfo^.Index)
- else
- Result:=TGetUnicodeStrProc(AMethod)();
- end;
- end;
- end;
- end;
- end;
- Procedure SetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: UnicodeString);
- type
- TSetUnicodeStrProcIndex=procedure(index:longint;s:UnicodeString) of object;
- TSetUnicodeStrProc=procedure(s:UnicodeString) of object;
- var
- AMethod : TMethod;
- begin
- case Propinfo^.PropType^.Kind of
- tkSString,tkAString:
- SetStrProp(Instance,PropInfo,Value);
- tkWString:
- SetWideStrProp(Instance,PropInfo,Value);
- tkUString:
- begin
- case (PropInfo^.PropProcs shr 2) and 3 of
- ptField:
- PUnicodeString(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
- TSetUnicodeStrProcIndex(AMethod)(PropInfo^.Index,Value)
- else
- TSetUnicodeStrProc(AMethod)(Value);
- end;
- end;
- end;
- end;
- end;
- {$ifndef FPUNONE}
- { ---------------------------------------------------------------------
- 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;
- TGetCurrencyProc = function : Currency of object;
- TGetCurrencyProcIndex = function(Index: integer) : Currency of object;
- 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)+PtrUInt(PropInfo^.GetProc))^;
- ftDouble:
- Result:=PDouble(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
- ftExtended:
- Result:=PExtended(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
- ftcomp:
- Result:=PComp(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
- ftcurr:
- Result:=PCurrency(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
- end;
- 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;
- 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);
- ftCurr:
- if ((PropInfo^.PropProcs shr 6) and 1)=0 then
- Result:=TGetCurrencyProc(AMethod)()
- else
- Result:=TGetCurrencyProcIndex(AMethod)(PropInfo^.Index);
- end;
- end;
- end;
- end;
- Procedure SetFloatProp(Instance : TObject;PropInfo : PPropInfo; Value : Extended);
- type
- TSetExtendedProc = procedure(const AValue: Extended) of object;
- TSetExtendedProcIndex = procedure(Index: integer; AValue: Extended) of object;
- TSetDoubleProc = procedure(const AValue: Double) of object;
- TSetDoubleProcIndex = procedure(Index: integer; AValue: Double) of object;
- TSetSingleProc = procedure(const AValue: Single) of object;
- TSetSingleProcIndex = procedure(Index: integer; AValue: Single) of object;
- TSetCurrencyProc = procedure(const AValue: Currency) of object;
- TSetCurrencyProcIndex = procedure(Index: integer; AValue: Currency) of object;
- Var
- AMethod : TMethod;
- begin
- case (PropInfo^.PropProcs shr 2) and 3 of
- ptfield:
- Case GetTypeData(PropInfo^.PropType)^.FloatType of
- ftSingle:
- PSingle(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
- ftDouble:
- PDouble(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
- ftExtended:
- PExtended(Pointer(Instance)+PtrUInt(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))^:=Comp(Value);
- {$endif FPC_COMP_IS_INT64}
- ftCurr:
- PCurrency(Pointer(Instance)+PtrUInt(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)+PtrUInt(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);
- ftCurr:
- if ((PropInfo^.PropProcs shr 6) and 1)=0 then
- TSetCurrencyProc(AMethod)(Value)
- else
- TSetCurrencyProcIndex(AMethod)(PropInfo^.Index,Value);
- 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;
- {$endif}
- { ---------------------------------------------------------------------
- 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)+PtrUInt(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)+PtrUInt(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:TMethod) of object;
- TSetMethodProc=procedure(p:TMethod) of object;
- var
- AMethod : TMethod;
- begin
- case (PropInfo^.PropProcs shr 2) and 3 of
- ptfield:
- PMethod(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
- 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:=PropType(Instance,PropName)=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.
|