1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234 |
- {
- $Id$
- 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}
- 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);
- TTOrdType = (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);
- TIntfFlags = set of (ifHasGuid,ifDispInterface,ifDispatch);
- {$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;
- PTypeData = ^TTypeData;
- TTypeData = packed record
- case TTypeKind of
- tkUnKnown,tkLString,tkWString,tkAString,tkVariant:
- ();
- tkInteger,tkChar,tkEnumeration,tkWChar:
- (OrdType : TTOrdType;
- 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 = packed record
- PropCount : Word;
- PropList : record end;
- end;
- 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) : 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) : Longint;
- Function GetOrdProp(Instance: TObject; const PropName: string): Longint;
- Procedure SetOrdProp(Instance: TObject; PropInfo : PPropInfo; Value : Longint);
- Procedure SetOrdProp(Instance: TObject; const PropName: string; Value: Longint);
- 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 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 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 GetObjectProp(Instance: TObject; const PropName: string): TObject;
- Function GetObjectProp(Instance: TObject; const PropName: string; MinClass: TClass): 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);
- // 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);
- Implementation
- ResourceString
- SErrPropertyNotFound = 'Unknown property: "%s"';
- SErrUnknownEnumValue = 'Unknown enumeration value: "%s"';
- type
- PMethod = ^TMethod;
- { ---------------------------------------------------------------------
- Auxiliary methods
- ---------------------------------------------------------------------}
- 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(pointer(TypeInfo)+2+PByte(pointer(TypeInfo)+1)^);
- end;
- { ---------------------------------------------------------------------
- Low-level calling of methods.
- ---------------------------------------------------------------------}
- {$I typinfo.inc}
- { ---------------------------------------------------------------------
- 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:=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(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;
- begin
- case (PropInfo^.PropProcs shr 4) and 3 of
- ptfield:
- IsStoredProp:=PBoolean(Pointer(Instance)+Longint(PropInfo^.StoredProc))^;
- ptstatic:
- IsStoredProp:=CallBooleanFunc(Instance,PropInfo^.StoredProc,0,0);
- ptvirtual:
- IsStoredProp:=CallBooleanFunc(Instance,ppointer(Pointer(Instance.ClassType)+Longint(PropInfo^.StoredProc))^,0,0);
- ptconst:
- IsStoredProp:=LongBool(PropInfo^.StoredProc);
- 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.
- }
- Type PWord = ^Word;
- Var TD : PTypeData;
- TP : PPropInfo;
- Count : Longint;
- begin
- TD:=GetTypeData(TypeInfo);
- // Get this objects TOTAL published properties count
- TP:=(@TD^.UnitName+Length(TD^.UnitName)+1);
- Count:=PWord(TP)^;
- // Now point TP to first propinfo record.
- Inc(Longint(TP),SizeOF(Word));
- While Count>0 do
- begin
- PropList^[0]:=TP;
- Inc(Longint(PropList),SizeOf(Pointer));
- // Point to TP next propinfo record.
- // Located at Name[Length(Name)+1] !
- TP:=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;
- Function GetPropList(TypeInfo : PTypeInfo;TypeKinds : TTypeKinds;
- PropList : PPropList) : Integer;
- {
- 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;
- begin
- 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
- InsertProp(PropList,PropInfo,Result);
- Inc(Result);
- end;
- end;
- finally
- FreeMem(TempList,Count*SizeOf(Pointer));
- end;
- end;
- end;
- Procedure SetIndexValues (P: PPRopInfo; Var Index,IValue : Longint);
- begin
- Index:=((P^.PropProcs shr 6) and 1);
- If Index<>0 then
- IValue:=P^.Index
- else
- IValue:=0;
- end;
- { ---------------------------------------------------------------------
- Property access functions
- ---------------------------------------------------------------------}
- { ---------------------------------------------------------------------
- Ordinal properties
- ---------------------------------------------------------------------}
- Function GetOrdProp(Instance : TObject;PropInfo : PPropInfo) : Longint;
- var
- value,Index,Ivalue : longint;
- TypeInfo: PTypeInfo;
- begin
- SetIndexValues(PropInfo,Index,Ivalue);
- case (PropInfo^.PropProcs) and 3 of
- ptfield:
- Value:=PLongint(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
- ptstatic:
- Value:=CallIntegerFunc(Instance,PropInfo^.GetProc,Index,IValue);
- ptvirtual:
- Value:=CallIntegerFunc(Instance,PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^,Index,IValue);
- end;
- { cut off unnecessary stuff }
- TypeInfo := PropInfo^.PropType;
- case TypeInfo^.Kind of
- tkChar, tkBool:
- Value:=Value and $ff;
- tkWChar:
- Value:=Value and $ffff;
- tkEnumeration,
- tkInteger:
- case GetTypeData(TypeInfo)^.OrdType of
- otSWord,otUWord:
- Value:=Value and $ffff;
- otSByte,otUByte:
- Value:=Value and $ff;
- end;
- end;
- GetOrdProp:=Value;
- end;
- Procedure SetOrdProp(Instance : TObject;PropInfo : PPropInfo;
- Value : Longint);
- var
- Index,IValue : Longint;
- DataSize: Integer;
- begin
- if PropInfo^.PropType^.Kind <> tkClass then
- { 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;
- else
- DataSize := 4;
- end
- else
- DataSize := 4;
- SetIndexValues(PropInfo,Index,Ivalue);
- case (PropInfo^.PropProcs shr 2) and 3 of
- ptfield:
- case DataSize of
- 1: PByte(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Byte(Value);
- 2: PWord(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Word(Value);
- 4: PLongint(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
- end;
- ptstatic:
- CallIntegerProc(Instance,PropInfo^.SetProc,Value,Index,IValue);
- ptvirtual:
- CallIntegerProc(Instance,PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.SetProc))^,Value,Index,IValue);
- end;
- end;
- Function GetOrdProp(Instance: TObject; const PropName: string): Longint;
- begin
- Result:=GetOrdProp(Instance,FindPropInfo(Instance,PropName));
- end;
- Procedure SetOrdProp(Instance: TObject; const PropName: string; Value: Longint);
- 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;
- { ---------------------------------------------------------------------
- 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; MinClass: TClass): TObject;
- begin
- Result:=TObject(GetOrdProp(Instance,PropInfo));
- 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
- SetOrdProp(Instance,PropInfo,Integer(Value));
- 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;
- var
- Index, IValue: LongInt;
- ShortResult: ShortString;
- begin
- SetIndexValues(PropInfo, Index, IValue);
- case Propinfo^.PropType^.Kind of
- tkSString:
- case (PropInfo^.PropProcs) and 3 of
- ptField:
- Result := PShortString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
- ptStatic:
- begin
- CallSStringFunc(Instance, PropInfo^.GetProc, Index, IValue, ShortResult);
- Result := ShortResult;
- end;
- ptVirtual:
- begin
- CallSStringFunc(Instance, PPointer(Pointer(Instance.ClassType) +
- LongWord(PropInfo^.GetProc))^, Index, IValue, ShortResult);
- Result := ShortResult;
- end;
- end;
- tkAString:
- case (PropInfo^.PropProcs) and 3 of
- ptField:
- Result := PAnsiString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
- ptStatic:
- Pointer(Result) := Pointer(LongWord(CallIntegerFunc(Instance, PropInfo^.GetProc, Index, IValue)));
- ptVirtual:
- Pointer(Result) := Pointer(LongWord(CallIntegerFunc(Instance,
- PPointer(Pointer(Instance.ClassType) + LongWord(PropInfo^.GetProc))^, Index, IValue)));
- end;
- else
- // Property is neither of type AnsiString nor of type ShortString
- SetLength(Result, 0);
- end;
- end;
- Procedure SetAStrProp(Instance : TObject;PropInfo : PPropInfo;
- const Value : AnsiString);
- {
- Dirty trick based on fact that AnsiString is just a pointer,
- hence can be treated like an integer type.
- }
- var
- Index,Ivalue : Longint;
- begin
- SetIndexValues(PropInfo,Index,IValue);
- case (PropInfo^.PropProcs shr 2) and 3 of
- ptfield:
- PAnsiString(Pointer(Instance) + Longint(PropInfo^.SetProc))^ := Value;
- ptstatic:
- CallIntegerProc(Instance,PropInfo^.SetProc,Longint(Pointer(Value)),Index,IValue);
- ptvirtual:
- CallIntegerProc(Instance,PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.SetProc))^,Longint(Pointer(Value)),Index,IValue);
- end;
- end;
- Procedure SetSStrProp(Instance : TObject;PropInfo : PPropInfo;
- const Value : ShortString);
- Var Index,IValue: longint;
- begin
- SetIndexValues(PRopInfo,Index,IValue);
- case (PropInfo^.PropProcs shr 2) and 3 of
- ptfield:
- PShortString(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
- ptstatic:
- CallSStringProc(Instance,PropInfo^.SetProc,Value,Index,IValue);
- ptvirtual:
- CallSStringProc(Instance,PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.SetProc))^,Value,Index,IValue);
- end;
- end;
- Procedure SetStrProp(Instance : TObject;PropInfo : PPropInfo;
- const Value : AnsiString);
- begin
- Case Propinfo^.PropType^.Kind of
- tkSString : SetSStrProp(Instance,PropInfo,Value);
- tkAString : SetAStrProp(Instance,Propinfo,Value);
- 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;
- { ---------------------------------------------------------------------
- Float properties
- ---------------------------------------------------------------------}
- Function GetFloatProp(Instance : TObject;PropInfo : PPropInfo) : Extended;
- var
- Index,Ivalue : longint;
- Value : Extended;
- begin
- SetIndexValues(PropInfo,Index,Ivalue);
- case (PropInfo^.PropProcs) and 3 of
- ptField:
- Case GetTypeData(PropInfo^.PropType)^.FloatType of
- ftSingle:
- Value:=PSingle(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
- ftDouble:
- Value:=PDouble(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
- ftExtended:
- Value:=PExtended(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
- {$ifndef cpum68k}
- ftcomp:
- Value:=PComp(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
- {$endif cpum68k}
- end;
- ptStatic:
- Case GetTypeData(PropInfo^.PropType)^.FloatType of
- ftSingle:
- Value:=CallSingleFunc(Instance,PropInfo^.GetProc,Index,IValue);
- ftDouble:
- Value:=CallDoubleFunc(Instance,PropInfo^.GetProc,Index,IValue);
- ftExtended:
- Value:=CallExtendedFunc(Instance,PropInfo^.GetProc,Index,IValue);
- end;
- ptVirtual:
- Case GetTypeData(PropInfo^.PropType)^.FloatType of
- ftSingle:
- Value:=CallSingleFunc(Instance,
- PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^,
- Index,IValue);
- ftDouble:
- Value:=CallDoubleFunc(Instance,
- PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^,
- Index,IValue);
- ftExtended:
- Value:=CallExtendedFunc(Instance,
- PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^,
- Index,IValue);
- end;
- end;
- Result:=Value;
- 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;
- Var IValue,Index : longint;
- AMethod: TMethod;
- begin
- SetIndexValues(PropInfo,Index,Ivalue);
- case (PropInfo^.PropProcs shr 2) and 3 of
- ptfield:
- Case GetTypeData(PropInfo^.PropType)^.FloatType of
- ftSingle:
- PSingle(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
- ftDouble:
- PDouble(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
- ftExtended:
- PExtended(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
- {$ifndef cpum68k}
- ftcomp:
- PComp(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Comp(Value);
- {$endif cpum68k}
- { Uncommenting this code results in a internal error!!
- ftFixed16:
- PFixed16(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
- ftfixed32:
- PFixed32(Pointer(Instance)+Longint(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)+Longint(PropInfo^.SetProc))^;
- AMethod.Data:=Instance;
- Case GetTypeData(PropInfo^.PropType)^.FloatType of
- ftSingle:
- if Index=0 then
- TSetSingleProc(AMethod)(Value)
- else
- TSetSingleProcIndex(AMethod)(IValue,Value);
- ftDouble:
- if Index=0 then
- TSetDoubleProc(AMethod)(Value)
- else
- TSetDoubleProcIndex(AMethod)(IValue,Value);
- ftExtended:
- if Index=0 then
- TSetExtendedProc(AMethod)(Value)
- else
- TSetExtendedProcIndex(AMethod)(IValue,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;
- { ---------------------------------------------------------------------
- Variant properties
- ---------------------------------------------------------------------}
- Function GetVariantProp(Instance : TObject;PropInfo : PPropInfo): Variant;
- begin
- {!!!!!!!!!!!}
- Result:=nil;
- end;
- Procedure SetVariantProp(Instance : TObject;PropInfo : PPropInfo;
- const Value: Variant);
- begin
- {!!!!!!!!!!!}
- 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;
- { ---------------------------------------------------------------------
- Method properties
- ---------------------------------------------------------------------}
- Function GetMethodProp(Instance : TObject;PropInfo : PPropInfo) : TMethod;
- var
- value: PMethod;
- Index,Ivalue : longint;
- begin
- SetIndexValues(PropInfo,Index,Ivalue);
- case (PropInfo^.PropProcs) and 3 of
- ptfield:
- Value:=PMethod(Pointer(Instance)+Longint(PropInfo^.GetProc));
- ptstatic:
- Value:=PMethod(LongInt(CallIntegerFunc(Instance,PropInfo^.GetProc,Index,IValue)));
- ptvirtual:
- Value:=PMethod(LongInt(CallIntegerFunc(Instance,PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^,Index,IValue)));
- end;
- GetMethodProp:=Value^;
- end;
- Procedure SetMethodProp(Instance : TObject;PropInfo : PPropInfo;
- const Value : TMethod);
- var
- Index,IValue : Longint;
- begin
- SetIndexValues(PropInfo,Index,Ivalue);
- case (PropInfo^.PropProcs shr 2) and 3 of
- ptfield:
- PMethod(Pointer(Instance)+Longint(PropInfo^.SetProc))^ := Value;
- ptstatic:
- CallIntegerProc(Instance,PropInfo^.SetProc,Integer(@Value), Index, IValue);
- ptvirtual:
- CallIntegerProc(Instance,
- PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.SetProc))^,
- Integer(@Value), Index, IValue);
- 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;
- { ---------------------------------------------------------------------
- Int64 properties
- ---------------------------------------------------------------------}
- Function GetInt64Prop(Instance: TObject; PropInfo: PPropInfo): Int64;
- var
- Index, IValue: LongInt;
- begin
- SetIndexValues(PropInfo,Index,Ivalue);
- case PropInfo^.PropProcs and 3 of
- ptfield:
- Result := PInt64(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
- ptstatic:
- Result := CallIntegerFunc(Instance, PropInfo^.GetProc, Index, IValue);
- ptvirtual:
- Result := CallIntegerFunc(Instance,
- PPointer(Pointer(Instance.ClassType) + LongInt(PropInfo^.GetProc))^,
- Index, IValue);
- end;
- end;
- procedure SetInt64Prop(Instance: TObject; PropInfo: PPropInfo; const Value: Int64);
- var
- Index, IValue: LongInt;
- begin
- SetIndexValues(PropInfo,Index,Ivalue);
- case PropInfo^.PropProcs and 3 of
- ptfield:
- PInt64(Pointer(Instance)+Longint(PropInfo^.GetProc))^ := Value;
- ptstatic:
- CallIntegerProc(Instance,PropInfo^.SetProc,Value,Index,IValue);
- ptvirtual:
- CallIntegerProc(Instance,PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.SetProc))^,Value,Index,IValue);
- end;
- 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;
- { ---------------------------------------------------------------------
- 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
- end;
- Procedure SetPropValue(Instance: TObject; const PropName: string; const Value: Variant);
- begin
- 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.
- {
- $Log$
- Revision 1.18 2003-10-24 08:37:20 marco
- * Fix from Peter
- Revision 1.17 2003/10/17 20:58:27 olle
- * Changed m68k to cpum68k, i386 to cpui386
- Revision 1.16 2003/04/24 11:46:25 florian
- * fixed wrong newlines
- Revision 1.15 2003/03/29 16:55:56 michael
- + Patch from Mattias Gaertner for single typeinfo
- Revision 1.14 2002/09/07 16:01:22 peter
- * old logs removed and tabs fixed
- Revision 1.13 2002/04/04 18:32:59 peter
- * merged getpropinfo fix
- }
|