typinfo.pp 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by Florian Klaempfl
  4. member of the Free Pascal development team
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. { This unit provides the same Functionality as the TypInfo Unit }
  12. { of Delphi }
  13. unit typinfo;
  14. interface
  15. {$MODE objfpc}
  16. {$inline on}
  17. {$h+}
  18. uses SysUtils;
  19. // temporary types:
  20. type
  21. {$MINENUMSIZE 1 this saves a lot of memory }
  22. // if you change one of the following enumeration types
  23. // you have also to change the compiler in an appropriate way !
  24. TTypeKind = (tkUnknown,tkInteger,tkChar,tkEnumeration,tkFloat,
  25. tkSet,tkMethod,tkSString,tkLString,tkAString,
  26. tkWString,tkVariant,tkArray,tkRecord,tkInterface,
  27. tkClass,tkObject,tkWChar,tkBool,tkInt64,tkQWord,
  28. tkDynArray,tkInterfaceRaw);
  29. TOrdType = (otSByte,otUByte,otSWord,otUWord,otSLong,otULong);
  30. {$ifndef FPUNONE}
  31. TFloatType = (ftSingle,ftDouble,ftExtended,ftComp,ftCurr);
  32. {$endif}
  33. TMethodKind = (mkProcedure,mkFunction,mkConstructor,mkDestructor,
  34. mkClassProcedure, mkClassFunction);
  35. TParamFlag = (pfVar,pfConst,pfArray,pfAddress,pfReference,pfOut);
  36. TParamFlags = set of TParamFlag;
  37. TIntfFlag = (ifHasGuid,ifDispInterface,ifDispatch,ifHasStrGUID);
  38. TIntfFlags = set of TIntfFlag;
  39. TIntfFlagsBase = set of TIntfFlag;
  40. {$MINENUMSIZE DEFAULT}
  41. const
  42. ptField = 0;
  43. ptStatic = 1;
  44. ptVirtual = 2;
  45. ptConst = 3;
  46. tkString = tkSString;
  47. type
  48. TTypeKinds = set of TTypeKind;
  49. ShortStringBase = string[255];
  50. {$PACKRECORDS 1}
  51. TTypeInfo = record
  52. Kind : TTypeKind;
  53. Name : ShortString;
  54. // here the type data follows as TTypeData record
  55. end;
  56. PTypeInfo = ^TTypeInfo;
  57. PPTypeInfo = ^PTypeInfo;
  58. {$PACKRECORDS C}
  59. PTypeData = ^TTypeData;
  60. TTypeData =
  61. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  62. packed
  63. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  64. record
  65. case TTypeKind of
  66. tkUnKnown,tkLString,tkWString,tkAString,tkVariant:
  67. ();
  68. tkInteger,tkChar,tkEnumeration,tkWChar,tkSet:
  69. (OrdType : TOrdType;
  70. case TTypeKind of
  71. tkInteger,tkChar,tkEnumeration,tkBool,tkWChar : (
  72. MinValue,MaxValue : Longint;
  73. case TTypeKind of
  74. tkEnumeration:
  75. (
  76. BaseType : PTypeInfo;
  77. NameList : ShortString)
  78. );
  79. tkSet:
  80. (CompType : PTypeInfo)
  81. );
  82. {$ifndef FPUNONE}
  83. tkFloat:
  84. (FloatType : TFloatType);
  85. {$endif}
  86. tkSString:
  87. (MaxLength : Byte);
  88. tkClass:
  89. (ClassType : TClass;
  90. ParentInfo : PTypeInfo;
  91. PropCount : SmallInt;
  92. UnitName : ShortString
  93. // here the properties follow as array of TPropInfo
  94. );
  95. tkMethod:
  96. (MethodKind : TMethodKind;
  97. ParamCount : Byte;
  98. ParamList : array[0..1023] of Char
  99. {in reality ParamList is a array[1..ParamCount] of:
  100. record
  101. Flags : TParamFlags;
  102. ParamName : ShortString;
  103. TypeName : ShortString;
  104. end;
  105. followed by
  106. ResultType : ShortString}
  107. );
  108. tkInt64:
  109. (MinInt64Value, MaxInt64Value: Int64);
  110. tkQWord:
  111. (MinQWordValue, MaxQWordValue: QWord);
  112. tkInterface:
  113. (
  114. IntfParent: PTypeInfo;
  115. IntfFlags : TIntfFlagsBase;
  116. GUID: TGUID;
  117. IntfUnit: ShortString;
  118. );
  119. tkInterfaceRaw:
  120. (
  121. RawIntfParent: PTypeInfo;
  122. RawIntfFlags : TIntfFlagsBase;
  123. IID: TGUID;
  124. RawIntfUnit: ShortString;
  125. IIDStr: ShortString;
  126. );
  127. tkDynArray:
  128. (
  129. elSize : PtrUInt;
  130. elType2 : PPTypeInfo;
  131. varType : Longint;
  132. elType : PPTypeInfo;
  133. DynUnitName: ShortStringBase
  134. );
  135. end;
  136. // unsed, just for completeness
  137. TPropData =
  138. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  139. packed
  140. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  141. record
  142. PropCount : Word;
  143. PropList : record _alignmentdummy : ptrint; end;
  144. end;
  145. {$PACKRECORDS 1}
  146. PPropInfo = ^TPropInfo;
  147. TPropInfo = packed record
  148. PropType : PTypeInfo;
  149. GetProc : Pointer;
  150. SetProc : Pointer;
  151. StoredProc : Pointer;
  152. Index : Integer;
  153. Default : Longint;
  154. NameIndex : SmallInt;
  155. // contains the type of the Get/Set/Storedproc, see also ptxxx
  156. // bit 0..1 GetProc
  157. // 2..3 SetProc
  158. // 4..5 StoredProc
  159. // 6 : true, constant index property
  160. PropProcs : Byte;
  161. Name : ShortString;
  162. end;
  163. TProcInfoProc = Procedure(PropInfo : PPropInfo) of object;
  164. PPropList = ^TPropList;
  165. TPropList = array[0..65535] of PPropInfo;
  166. const
  167. tkAny = [Low(TTypeKind)..High(TTypeKind)];
  168. tkMethods = [tkMethod];
  169. tkProperties = tkAny-tkMethods-[tkUnknown];
  170. // general property handling
  171. Function GetTypeData(TypeInfo : PTypeInfo) : PTypeData;
  172. Function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string) : PPropInfo;
  173. Function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string; AKinds : TTypeKinds) : PPropInfo;
  174. Function GetPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds) : PPropInfo;
  175. Function GetPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  176. Function GetPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds) : PPropInfo;
  177. Function GetPropInfo(AClass: TClass; const PropName: string): PPropInfo;
  178. Function FindPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  179. Function FindPropInfo(AClass:TClass;const PropName: string): PPropInfo;
  180. Procedure GetPropInfos(TypeInfo : PTypeInfo;PropList : PPropList);
  181. Function GetPropList(TypeInfo : PTypeInfo;TypeKinds : TTypeKinds; PropList : PPropList;Sorted : boolean = true):longint;
  182. Function GetPropList(TypeInfo: PTypeInfo; out PropList: PPropList): SizeInt;
  183. function GetPropList(AObject: TObject; out PropList: PPropList): Integer;
  184. // Property information routines.
  185. Function IsStoredProp(Instance: TObject;PropInfo : PPropInfo) : Boolean;
  186. Function IsStoredProp(Instance: TObject; const PropName: string): Boolean;
  187. Function IsPublishedProp(Instance: TObject; const PropName: string): Boolean;
  188. Function IsPublishedProp(AClass: TClass; const PropName: string): Boolean;
  189. Function PropType(Instance: TObject; const PropName: string): TTypeKind;
  190. Function PropType(AClass: TClass; const PropName: string): TTypeKind;
  191. Function PropIsType(Instance: TObject; const PropName: string; TypeKind: TTypeKind): Boolean;
  192. Function PropIsType(AClass: TClass; const PropName: string; TypeKind: TTypeKind): Boolean;
  193. // subroutines to read/write properties
  194. Function GetOrdProp(Instance: TObject; PropInfo : PPropInfo) : Int64;
  195. Function GetOrdProp(Instance: TObject; const PropName: string): Int64;
  196. Procedure SetOrdProp(Instance: TObject; PropInfo : PPropInfo; Value : Int64);
  197. Procedure SetOrdProp(Instance: TObject; const PropName: string; Value: Int64);
  198. Function GetEnumProp(Instance: TObject; const PropName: string): string;
  199. Function GetEnumProp(Instance: TObject; const PropInfo: PPropInfo): string;
  200. Procedure SetEnumProp(Instance: TObject; const PropName: string;const Value: string);
  201. Procedure SetEnumProp(Instance: TObject; const PropInfo: PPropInfo;const Value: string);
  202. Function GetSetProp(Instance: TObject; const PropName: string): string;
  203. Function GetSetProp(Instance: TObject; const PropName: string; Brackets: Boolean): string;
  204. Function GetSetProp(Instance: TObject; const PropInfo: PPropInfo; Brackets: Boolean): string;
  205. Procedure SetSetProp(Instance: TObject; const PropName: string; const Value: string);
  206. Procedure SetSetProp(Instance: TObject; const PropInfo: PPropInfo; const Value: string);
  207. Function GetStrProp(Instance: TObject; PropInfo : PPropInfo) : Ansistring;
  208. Function GetStrProp(Instance: TObject; const PropName: string): string;
  209. Procedure SetStrProp(Instance: TObject; const PropName: string; const Value: AnsiString);
  210. Procedure SetStrProp(Instance: TObject; PropInfo : PPropInfo; const Value : Ansistring);
  211. Function GetWideStrProp(Instance: TObject; PropInfo: PPropInfo): WideString;
  212. Function GetWideStrProp(Instance: TObject; const PropName: string): WideString;
  213. Procedure SetWideStrProp(Instance: TObject; const PropName: string; const Value: WideString);
  214. Procedure SetWideStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: WideString);
  215. {$ifndef FPUNONE}
  216. Function GetFloatProp(Instance: TObject; PropInfo : PPropInfo) : Extended;
  217. Function GetFloatProp(Instance: TObject; const PropName: string): Extended;
  218. Procedure SetFloatProp(Instance: TObject; const PropName: string; Value: Extended);
  219. Procedure SetFloatProp(Instance: TObject; PropInfo : PPropInfo; Value : Extended);
  220. {$endif}
  221. Function GetObjectProp(Instance: TObject; const PropName: string): TObject;
  222. Function GetObjectProp(Instance: TObject; const PropName: string; MinClass: TClass): TObject;
  223. Function GetObjectProp(Instance: TObject; PropInfo: PPropInfo): TObject;
  224. Function GetObjectProp(Instance: TObject; PropInfo: PPropInfo; MinClass: TClass): TObject;
  225. Procedure SetObjectProp(Instance: TObject; const PropName: string; Value: TObject);
  226. Procedure SetObjectProp(Instance: TObject; PropInfo: PPropInfo; Value: TObject);
  227. Function GetObjectPropClass(Instance: TObject; const PropName: string): TClass;
  228. Function GetMethodProp(Instance: TObject; PropInfo: PPropInfo) : TMethod;
  229. Function GetMethodProp(Instance: TObject; const PropName: string): TMethod;
  230. Procedure SetMethodProp(Instance: TObject; PropInfo: PPropInfo; const Value : TMethod);
  231. Procedure SetMethodProp(Instance: TObject; const PropName: string; const Value: TMethod);
  232. Function GetInt64Prop(Instance: TObject; PropInfo: PPropInfo): Int64;
  233. Function GetInt64Prop(Instance: TObject; const PropName: string): Int64;
  234. Procedure SetInt64Prop(Instance: TObject; PropInfo: PPropInfo; const Value: Int64);
  235. Procedure SetInt64Prop(Instance: TObject; const PropName: string; const Value: Int64);
  236. Function GetPropValue(Instance: TObject; const PropName: string): Variant;
  237. Function GetPropValue(Instance: TObject; const PropName: string; PreferStrings: Boolean): Variant;
  238. Procedure SetPropValue(Instance: TObject; const PropName: string; const Value: Variant);
  239. Function GetVariantProp(Instance: TObject; PropInfo : PPropInfo): Variant;
  240. Function GetVariantProp(Instance: TObject; const PropName: string): Variant;
  241. Procedure SetVariantProp(Instance: TObject; const PropName: string; const Value: Variant);
  242. Procedure SetVariantProp(Instance: TObject; PropInfo : PPropInfo; const Value: Variant);
  243. function GetInterfaceProp(Instance: TObject; const PropName: string): IInterface;
  244. function GetInterfaceProp(Instance: TObject; PropInfo: PPropInfo): IInterface;
  245. procedure SetInterfaceProp(Instance: TObject; const PropName: string; const Value: IInterface);
  246. procedure SetInterfaceProp(Instance: TObject; PropInfo: PPropInfo; const Value: IInterface);
  247. // Auxiliary routines, which may be useful
  248. Function GetEnumName(TypeInfo : PTypeInfo;Value : Integer) : string;
  249. Function GetEnumValue(TypeInfo : PTypeInfo;const Name : string) : Integer;
  250. function GetEnumNameCount(enum1: PTypeInfo): SizeInt;
  251. function SetToString(TypeInfo: PTypeInfo; Value: Integer; Brackets: Boolean) : String;
  252. function SetToString(PropInfo: PPropInfo; Value: Integer; Brackets: Boolean) : String;
  253. function SetToString(PropInfo: PPropInfo; Value: Integer) : String;
  254. function StringToSet(PropInfo: PPropInfo; const Value: string): Integer;
  255. function StringToSet(TypeInfo: PTypeInfo; const Value: string): Integer;
  256. const
  257. BooleanIdents: array[Boolean] of String = ('False', 'True');
  258. DotSep: String = '.';
  259. Type
  260. EPropertyError = Class(Exception);
  261. TGetPropValue = Function (Instance: TObject; const PropName: string; PreferStrings: Boolean) : Variant;
  262. TSetPropValue = Procedure (Instance: TObject; const PropName: string; const Value: Variant);
  263. TGetVariantProp = Function (Instance: TObject; PropInfo : PPropInfo): Variant;
  264. TSetVariantProp = Procedure (Instance: TObject; PropInfo : PPropInfo; const Value: Variant);
  265. EPropertyConvertError = class(Exception); // Not used (yet), but defined for compatibility.
  266. Const
  267. OnGetPropValue : TGetPropValue = Nil;
  268. OnSetPropValue : TSetPropValue = Nil;
  269. OnGetVariantprop : TGetVariantProp = Nil;
  270. OnSetVariantprop : TSetVariantProp = Nil;
  271. Implementation
  272. uses rtlconsts;
  273. type
  274. PMethod = ^TMethod;
  275. { ---------------------------------------------------------------------
  276. Auxiliary methods
  277. ---------------------------------------------------------------------}
  278. function aligntoptr(p : pointer) : pointer;inline;
  279. begin
  280. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  281. result:=align(p,sizeof(p));
  282. {$else FPC_REQUIRES_PROPER_ALIGNMENT}
  283. result:=p;
  284. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  285. end;
  286. Function GetEnumName(TypeInfo : PTypeInfo;Value : Integer) : string;
  287. Var PS : PShortString;
  288. PT : PTypeData;
  289. begin
  290. PT:=GetTypeData(TypeInfo);
  291. if TypeInfo^.Kind=tkBool then
  292. begin
  293. case Value of
  294. 0,1:
  295. Result:=BooleanIdents[Boolean(Value)];
  296. else
  297. Result:='';
  298. end;
  299. end
  300. else
  301. begin
  302. PS:=@PT^.NameList;
  303. While Value>0 Do
  304. begin
  305. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  306. Dec(Value);
  307. end;
  308. Result:=PS^;
  309. end;
  310. end;
  311. Function GetEnumValue(TypeInfo : PTypeInfo;const Name : string) : Integer;
  312. Var PS : PShortString;
  313. PT : PTypeData;
  314. Count : longint;
  315. sName: shortstring;
  316. begin
  317. If Length(Name)=0 then
  318. exit(-1);
  319. sName := Name;
  320. PT:=GetTypeData(TypeInfo);
  321. Count:=0;
  322. Result:=-1;
  323. if TypeInfo^.Kind=tkBool then
  324. begin
  325. If CompareText(BooleanIdents[false],Name)=0 then
  326. result:=0
  327. else if CompareText(BooleanIdents[true],Name)=0 then
  328. result:=1;
  329. end
  330. else
  331. begin
  332. PS:=@PT^.NameList;
  333. While (Result=-1) and (PByte(PS)^<>0) do
  334. begin
  335. If ShortCompareText(PS^, sName) = 0 then
  336. Result:=Count;
  337. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  338. Inc(Count);
  339. end;
  340. end;
  341. end;
  342. function GetEnumNameCount(enum1: PTypeInfo): SizeInt;
  343. var
  344. PS: PShortString;
  345. PT: PTypeData;
  346. Count: SizeInt;
  347. begin
  348. PT:=GetTypeData(enum1);
  349. if enum1^.Kind=tkBool then
  350. Result:=2
  351. else
  352. begin
  353. Count:=0;
  354. Result:=0;
  355. PS:=@PT^.NameList;
  356. While (PByte(PS)^<>0) do
  357. begin
  358. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  359. Inc(Count);
  360. end;
  361. Result := Count;
  362. end;
  363. end;
  364. Function SetToString(PropInfo: PPropInfo; Value: Integer; Brackets: Boolean) : String;
  365. begin
  366. Result:=SetToString(PropInfo^.PropType,Value,Brackets);
  367. end;
  368. Function SetToString(TypeInfo: PTypeInfo; Value: Integer; Brackets: Boolean) : String;
  369. {$ifdef FPC_NEW_BIGENDIAN_SETS}
  370. type
  371. tsetarr = bitpacked array[0..31] of 0..1;
  372. {$endif}
  373. Var
  374. I : Integer;
  375. PTI : PTypeInfo;
  376. begin
  377. {$if defined(FPC_NEW_BIGENDIAN_SETS) and defined(FPC_BIG_ENDIAN)}
  378. case GetTypeData(TypeInfo)^.OrdType of
  379. otSByte,otUByte: Value:=Value shl 24;
  380. otSWord,otUWord: Value:=Value shl 16;
  381. end;
  382. {$endif}
  383. PTI:=GetTypeData(TypeInfo)^.CompType;
  384. Result:='';
  385. For I:=0 to SizeOf(Integer)*8-1 do
  386. begin
  387. {$ifdef FPC_NEW_BIGENDIAN_SETS}
  388. if (tsetarr(Value)[i]<>0) then
  389. {$else}
  390. if ((Value and 1)<>0) then
  391. {$endif}
  392. begin
  393. If Result='' then
  394. Result:=GetEnumName(PTI,i)
  395. else
  396. Result:=Result+','+GetEnumName(PTI,I);
  397. end;
  398. {$ifndef FPC_NEW_BIGENDIAN_SETS}
  399. Value:=Value shr 1;
  400. {$endif FPC_NEW_BIGENDIAN_SETS}
  401. end;
  402. if Brackets then
  403. Result:='['+Result+']';
  404. end;
  405. Function SetToString(PropInfo: PPropInfo; Value: Integer) : String;
  406. begin
  407. Result:=SetToString(PropInfo,Value,False);
  408. end;
  409. Const
  410. SetDelim = ['[',']',',',' '];
  411. Function GetNextElement(Var S : String) : String;
  412. Var
  413. J : Integer;
  414. begin
  415. J:=1;
  416. Result:='';
  417. If Length(S)>0 then
  418. begin
  419. While (J<=Length(S)) and Not (S[j] in SetDelim) do
  420. Inc(j);
  421. Result:=Copy(S,1,j-1);
  422. Delete(S,1,j);
  423. end;
  424. end;
  425. Function StringToSet(PropInfo: PPropInfo; const Value: string): Integer;
  426. begin
  427. Result:=StringToSet(PropInfo^.PropType,Value);
  428. end;
  429. Function StringToSet(TypeInfo: PTypeInfo; const Value: string): Integer;
  430. Var
  431. S,T : String;
  432. I : Integer;
  433. PTI : PTypeInfo;
  434. begin
  435. Result:=0;
  436. PTI:=GetTypeData(TypeInfo)^.Comptype;
  437. S:=Value;
  438. I:=1;
  439. If Length(S)>0 then
  440. begin
  441. While (I<=Length(S)) and (S[i] in SetDelim) do
  442. Inc(I);
  443. Delete(S,1,i-1);
  444. end;
  445. While (S<>'') do
  446. begin
  447. T:=GetNextElement(S);
  448. if T<>'' then
  449. begin
  450. I:=GetEnumValue(PTI,T);
  451. if (I<0) then
  452. raise EPropertyError.CreateFmt(SErrUnknownEnumValue, [T]);
  453. Result:=Result or (1 shl i);
  454. end;
  455. end;
  456. end;
  457. Function GetTypeData(TypeInfo : PTypeInfo) : PTypeData;
  458. begin
  459. GetTypeData:=PTypeData(aligntoptr(PTypeData(pointer(TypeInfo)+2+PByte(pointer(TypeInfo)+1)^)));
  460. end;
  461. { ---------------------------------------------------------------------
  462. Basic Type information functions.
  463. ---------------------------------------------------------------------}
  464. Function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string) : PPropInfo;
  465. var
  466. hp : PTypeData;
  467. i : longint;
  468. p : shortstring;
  469. pd : ^TPropData;
  470. begin
  471. P:=PropName; // avoid Ansi<->short conversion in a loop
  472. while Assigned(TypeInfo) do
  473. begin
  474. // skip the name
  475. hp:=GetTypeData(Typeinfo);
  476. // the class info rtti the property rtti follows immediatly
  477. pd:=aligntoptr(pointer(pointer(@hp^.UnitName)+Length(hp^.UnitName)+1));
  478. Result:=PPropInfo(@pd^.PropList);
  479. for i:=1 to pd^.PropCount do
  480. begin
  481. // found a property of that name ?
  482. if ShortCompareText(Result^.Name, P) = 0 then
  483. exit;
  484. // skip to next property
  485. Result:=PPropInfo(aligntoptr(pointer(@Result^.Name)+byte(Result^.Name[0])+1));
  486. end;
  487. // parent class
  488. Typeinfo:=hp^.ParentInfo;
  489. end;
  490. Result:=Nil;
  491. end;
  492. Function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string; Akinds : TTypeKinds) : PPropInfo;
  493. begin
  494. Result:=GetPropInfo(TypeInfo,PropName);
  495. If (Akinds<>[]) then
  496. If (Result<>Nil) then
  497. If Not (Result^.PropType^.Kind in AKinds) then
  498. Result:=Nil;
  499. end;
  500. Function GetPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds) : PPropInfo;
  501. begin
  502. Result:=GetPropInfo(PTypeInfo(AClass.ClassInfo),PropName,AKinds);
  503. end;
  504. Function GetPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds) : PPropInfo;
  505. begin
  506. Result:=GetPropInfo(Instance.ClassType,PropName,AKinds);
  507. end;
  508. Function GetPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  509. begin
  510. Result:=GetPropInfo(Instance,PropName,[]);
  511. end;
  512. Function GetPropInfo(AClass: TClass; const PropName: string): PPropInfo;
  513. begin
  514. Result:=GetPropInfo(AClass,PropName,[]);
  515. end;
  516. Function FindPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  517. begin
  518. result:=GetPropInfo(Instance, PropName);
  519. if Result=nil then
  520. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  521. end;
  522. Function FindPropInfo(AClass:TClass;const PropName: string): PPropInfo;
  523. begin
  524. result:=GetPropInfo(AClass,PropName);
  525. if result=nil then
  526. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  527. end;
  528. Function IsStoredProp(Instance : TObject;PropInfo : PPropInfo) : Boolean;
  529. type
  530. TBooleanIndexFunc=function(Index:integer):boolean of object;
  531. TBooleanFunc=function:boolean of object;
  532. var
  533. AMethod : TMethod;
  534. begin
  535. case (PropInfo^.PropProcs shr 4) and 3 of
  536. ptfield:
  537. Result:=PBoolean(Pointer(Instance)+PtrUInt(PropInfo^.StoredProc))^;
  538. ptconst:
  539. Result:=LongBool(PropInfo^.StoredProc);
  540. ptstatic,
  541. ptvirtual:
  542. begin
  543. if (PropInfo^.PropProcs shr 4) and 3=ptstatic then
  544. AMethod.Code:=PropInfo^.StoredProc
  545. else
  546. AMethod.Code:=ppointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.StoredProc))^;
  547. AMethod.Data:=Instance;
  548. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  549. Result:=TBooleanIndexFunc(AMethod)(PropInfo^.Index)
  550. else
  551. Result:=TBooleanFunc(AMethod)();
  552. end;
  553. end;
  554. end;
  555. Procedure GetPropInfos(TypeInfo : PTypeInfo;PropList : PPropList);
  556. {
  557. Store Pointers to property information in the list pointed
  558. to by proplist. PRopList must contain enough space to hold ALL
  559. properties.
  560. }
  561. Var
  562. TD : PTypeData;
  563. TP : PPropInfo;
  564. Count : Longint;
  565. begin
  566. // Get this objects TOTAL published properties count
  567. TD:=GetTypeData(TypeInfo);
  568. // Clear list
  569. FillChar(PropList^,TD^.PropCount*sizeof(Pointer),0);
  570. repeat
  571. TD:=GetTypeData(TypeInfo);
  572. // published properties count for this object
  573. TP:=aligntoptr(PPropInfo(aligntoptr((Pointer(@TD^.UnitName)+Length(TD^.UnitName)+1))));
  574. Count:=PWord(TP)^;
  575. // Now point TP to first propinfo record.
  576. Inc(Pointer(TP),SizeOF(Word));
  577. tp:=aligntoptr(tp);
  578. While Count>0 do
  579. begin
  580. // Don't overwrite properties with the same name
  581. if PropList^[TP^.NameIndex]=nil then
  582. PropList^[TP^.NameIndex]:=TP;
  583. // Point to TP next propinfo record.
  584. // Located at Name[Length(Name)+1] !
  585. TP:=aligntoptr(PPropInfo(pointer(@TP^.Name)+PByte(@TP^.Name)^+1));
  586. Dec(Count);
  587. end;
  588. TypeInfo:=TD^.Parentinfo;
  589. until TypeInfo=nil;
  590. end;
  591. Procedure InsertProp (PL : PProplist;PI : PPropInfo; Count : longint);
  592. Var
  593. I : Longint;
  594. begin
  595. I:=0;
  596. While (I<Count) and (PI^.Name>PL^[I]^.Name) do
  597. Inc(I);
  598. If I<Count then
  599. Move(PL^[I], PL^[I+1], (Count - I) * SizeOf(Pointer));
  600. PL^[I]:=PI;
  601. end;
  602. Procedure InsertPropnosort (PL : PProplist;PI : PPropInfo; Count : longint);
  603. begin
  604. PL^[Count]:=PI;
  605. end;
  606. Type TInsertProp = Procedure (PL : PProplist;PI : PPropInfo; Count : longint);
  607. //Const InsertProps : array[false..boolean] of TInsertProp = (InsertPropNoSort,InsertProp);
  608. Function GetPropList(TypeInfo : PTypeInfo;TypeKinds : TTypeKinds; PropList : PPropList;Sorted : boolean = true):longint;
  609. {
  610. Store Pointers to property information OF A CERTAIN KIND in the list pointed
  611. to by proplist. PRopList must contain enough space to hold ALL
  612. properties.
  613. }
  614. Var
  615. TempList : PPropList;
  616. PropInfo : PPropinfo;
  617. I,Count : longint;
  618. DoInsertProp : TInsertProp;
  619. begin
  620. if sorted then
  621. DoInsertProp:=@InsertProp
  622. else
  623. DoInsertProp:=@InsertPropnosort;
  624. Result:=0;
  625. Count:=GetTypeData(TypeInfo)^.Propcount;
  626. If Count>0 then
  627. begin
  628. GetMem(TempList,Count*SizeOf(Pointer));
  629. Try
  630. GetPropInfos(TypeInfo,TempList);
  631. For I:=0 to Count-1 do
  632. begin
  633. PropInfo:=TempList^[i];
  634. If PropInfo^.PropType^.Kind in TypeKinds then
  635. begin
  636. If (PropList<>Nil) then
  637. DoInsertProp(PropList,PropInfo,Result);
  638. Inc(Result);
  639. end;
  640. end;
  641. finally
  642. FreeMem(TempList,Count*SizeOf(Pointer));
  643. end;
  644. end;
  645. end;
  646. Function GetPropList(TypeInfo: PTypeInfo; out PropList: PPropList): SizeInt;
  647. begin
  648. result:=GetTypeData(TypeInfo)^.Propcount;
  649. if result>0 then
  650. begin
  651. getmem(PropList,result*sizeof(pointer));
  652. GetPropInfos(TypeInfo,PropList);
  653. end
  654. else
  655. PropList:=Nil;
  656. end;
  657. function GetPropList(AObject: TObject; out PropList: PPropList): Integer;
  658. begin
  659. Result := GetPropList(PTypeInfo(AObject.ClassInfo), PropList);
  660. end;
  661. { ---------------------------------------------------------------------
  662. Property access functions
  663. ---------------------------------------------------------------------}
  664. { ---------------------------------------------------------------------
  665. Ordinal properties
  666. ---------------------------------------------------------------------}
  667. Function GetOrdProp(Instance : TObject;PropInfo : PPropInfo) : Int64;
  668. type
  669. TGetInt64ProcIndex=function(index:longint):Int64 of object;
  670. TGetInt64Proc=function():Int64 of object;
  671. TGetIntegerProcIndex=function(index:longint):longint of object;
  672. TGetIntegerProc=function:longint of object;
  673. TGetWordProcIndex=function(index:longint):word of object;
  674. TGetWordProc=function:word of object;
  675. TGetByteProcIndex=function(index:longint):Byte of object;
  676. TGetByteProc=function:Byte of object;
  677. var
  678. TypeInfo: PTypeInfo;
  679. AMethod : TMethod;
  680. DataSize: Integer;
  681. OrdType: TOrdType;
  682. Signed: Boolean;
  683. begin
  684. Result:=0;
  685. TypeInfo := PropInfo^.PropType;
  686. Signed := false;
  687. DataSize := 4;
  688. case TypeInfo^.Kind of
  689. {$ifdef cpu64}
  690. tkInterface,
  691. tkInterfaceRaw,
  692. tkDynArray,
  693. tkClass:
  694. DataSize:=8;
  695. {$endif cpu64}
  696. tkChar, tkBool:
  697. DataSize:=1;
  698. tkWChar:
  699. DataSize:=2;
  700. tkSet,
  701. tkEnumeration,
  702. tkInteger:
  703. begin
  704. OrdType:=GetTypeData(TypeInfo)^.OrdType;
  705. case OrdType of
  706. otSByte,otUByte: DataSize := 1;
  707. otSWord,otUWord: DataSize := 2;
  708. end;
  709. Signed := OrdType in [otSByte,otSWord,otSLong];
  710. end;
  711. tkInt64 :
  712. begin
  713. DataSize:=8;
  714. Signed:=true;
  715. end;
  716. tkQword :
  717. begin
  718. DataSize:=8;
  719. Signed:=false;
  720. end;
  721. end;
  722. case (PropInfo^.PropProcs) and 3 of
  723. ptfield:
  724. if Signed then begin
  725. case DataSize of
  726. 1: Result:=PShortInt(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  727. 2: Result:=PSmallInt(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  728. 4: Result:=PLongint(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  729. 8: Result:=PInt64(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  730. end;
  731. end else begin
  732. case DataSize of
  733. 1: Result:=PByte(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  734. 2: Result:=PWord(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  735. 4: Result:=PLongint(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  736. 8: Result:=PInt64(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  737. end;
  738. end;
  739. ptstatic,
  740. ptvirtual :
  741. begin
  742. if (PropInfo^.PropProcs and 3)=ptStatic then
  743. AMethod.Code:=PropInfo^.GetProc
  744. else
  745. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  746. AMethod.Data:=Instance;
  747. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then begin
  748. case DataSize of
  749. 1: Result:=TGetByteProcIndex(AMethod)(PropInfo^.Index);
  750. 2: Result:=TGetWordProcIndex(AMethod)(PropInfo^.Index);
  751. 4: Result:=TGetIntegerProcIndex(AMethod)(PropInfo^.Index);
  752. 8: result:=TGetInt64ProcIndex(AMethod)(PropInfo^.Index)
  753. end;
  754. end else begin
  755. case DataSize of
  756. 1: Result:=TGetByteProc(AMethod)();
  757. 2: Result:=TGetWordProc(AMethod)();
  758. 4: Result:=TGetIntegerProc(AMethod)();
  759. 8: result:=TGetInt64Proc(AMethod)();
  760. end;
  761. end;
  762. if Signed then begin
  763. case DataSize of
  764. 1: Result:=ShortInt(Result);
  765. 2: Result:=SmallInt(Result);
  766. end;
  767. end;
  768. end;
  769. end;
  770. end;
  771. Procedure SetOrdProp(Instance : TObject;PropInfo : PPropInfo;Value : Int64);
  772. type
  773. TSetInt64ProcIndex=procedure(index:longint;i:Int64) of object;
  774. TSetInt64Proc=procedure(i:Int64) of object;
  775. TSetIntegerProcIndex=procedure(index,i:longint) of object;
  776. TSetIntegerProc=procedure(i:longint) of object;
  777. var
  778. DataSize: Integer;
  779. AMethod : TMethod;
  780. begin
  781. if PropInfo^.PropType^.Kind in [tkInt64,tkQword
  782. { why do we have to handle classes here, see also below? (FK) }
  783. {$ifdef cpu64}
  784. ,tkInterface
  785. ,tkInterfaceRaw
  786. ,tkDynArray
  787. ,tkClass
  788. {$endif cpu64}
  789. ] then
  790. DataSize := 8
  791. else
  792. DataSize := 4;
  793. if not(PropInfo^.PropType^.Kind in [tkInt64,tkQword,tkClass]) then
  794. begin
  795. { cut off unnecessary stuff }
  796. case GetTypeData(PropInfo^.PropType)^.OrdType of
  797. otSWord,otUWord:
  798. begin
  799. Value:=Value and $ffff;
  800. DataSize := 2;
  801. end;
  802. otSByte,otUByte:
  803. begin
  804. Value:=Value and $ff;
  805. DataSize := 1;
  806. end;
  807. end;
  808. end;
  809. case (PropInfo^.PropProcs shr 2) and 3 of
  810. ptfield:
  811. case DataSize of
  812. 1: PByte(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Byte(Value);
  813. 2: PWord(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Word(Value);
  814. 4: PLongint(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Longint(Value);
  815. 8: PInt64(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  816. end;
  817. ptstatic,
  818. ptvirtual :
  819. begin
  820. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  821. AMethod.Code:=PropInfo^.SetProc
  822. else
  823. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  824. AMethod.Data:=Instance;
  825. if datasize=8 then
  826. begin
  827. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  828. TSetInt64ProcIndex(AMethod)(PropInfo^.Index,Value)
  829. else
  830. TSetInt64Proc(AMethod)(Value);
  831. end
  832. else
  833. begin
  834. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  835. TSetIntegerProcIndex(AMethod)(PropInfo^.Index,Value)
  836. else
  837. TSetIntegerProc(AMethod)(Value);
  838. end;
  839. end;
  840. end;
  841. end;
  842. Function GetOrdProp(Instance: TObject; const PropName: string): Int64;
  843. begin
  844. Result:=GetOrdProp(Instance,FindPropInfo(Instance,PropName));
  845. end;
  846. Procedure SetOrdProp(Instance: TObject; const PropName: string; Value: Int64);
  847. begin
  848. SetOrdProp(Instance,FindPropInfo(Instance,PropName),Value);
  849. end;
  850. Function GetEnumProp(Instance: TObject; Const PropInfo: PPropInfo): string;
  851. begin
  852. Result:=GetEnumName(PropInfo^.PropType, GetOrdProp(Instance, PropInfo));
  853. end;
  854. Function GetEnumProp(Instance: TObject; const PropName: string): string;
  855. begin
  856. Result:=GetEnumProp(Instance,FindPropInfo(Instance,PropName));
  857. end;
  858. Procedure SetEnumProp(Instance: TObject; const PropName: string; const Value: string);
  859. begin
  860. SetEnumProp(Instance,FindPropInfo(Instance,PropName),Value);
  861. end;
  862. Procedure SetEnumProp(Instance: TObject; Const PropInfo : PPropInfo; const Value: string);
  863. Var
  864. PV : Longint;
  865. begin
  866. If PropInfo<>Nil then
  867. begin
  868. PV:=GetEnumValue(PropInfo^.PropType, Value);
  869. if (PV<0) then
  870. raise EPropertyError.CreateFmt(SErrUnknownEnumValue, [Value]);
  871. SetOrdProp(Instance, PropInfo,PV);
  872. end;
  873. end;
  874. { ---------------------------------------------------------------------
  875. Int64 wrappers
  876. ---------------------------------------------------------------------}
  877. Function GetInt64Prop(Instance: TObject; PropInfo: PPropInfo): Int64;
  878. begin
  879. Result:=GetOrdProp(Instance,PropInfo);
  880. end;
  881. procedure SetInt64Prop(Instance: TObject; PropInfo: PPropInfo; const Value: Int64);
  882. begin
  883. SetOrdProp(Instance,PropInfo,Value);
  884. end;
  885. Function GetInt64Prop(Instance: TObject; const PropName: string): Int64;
  886. begin
  887. Result:=GetInt64Prop(Instance,FindPropInfo(Instance,PropName));
  888. end;
  889. Procedure SetInt64Prop(Instance: TObject; const PropName: string; const Value: Int64);
  890. begin
  891. SetInt64Prop(Instance,FindPropInfo(Instance,PropName),Value);
  892. end;
  893. { ---------------------------------------------------------------------
  894. Set properties
  895. ---------------------------------------------------------------------}
  896. Function GetSetProp(Instance: TObject; const PropName: string): string;
  897. begin
  898. Result:=GetSetProp(Instance,PropName,False);
  899. end;
  900. Function GetSetProp(Instance: TObject; const PropName: string; Brackets: Boolean): string;
  901. begin
  902. Result:=GetSetProp(Instance,FindPropInfo(Instance,PropName),Brackets);
  903. end;
  904. Function GetSetProp(Instance: TObject; const PropInfo: PPropInfo; Brackets: Boolean): string;
  905. begin
  906. Result:=SetToString(PropInfo,GetOrdProp(Instance,PropInfo),Brackets);
  907. end;
  908. Procedure SetSetProp(Instance: TObject; const PropName: string; const Value: string);
  909. begin
  910. SetSetProp(Instance,FindPropInfo(Instance,PropName),Value);
  911. end;
  912. Procedure SetSetProp(Instance: TObject; const PropInfo: PPropInfo; const Value: string);
  913. begin
  914. SetOrdProp(Instance,PropInfo,StringToSet(PropInfo,Value));
  915. end;
  916. { ---------------------------------------------------------------------
  917. Object properties
  918. ---------------------------------------------------------------------}
  919. Function GetObjectProp(Instance: TObject; const PropName: string): TObject;
  920. begin
  921. Result:=GetObjectProp(Instance,PropName,Nil);
  922. end;
  923. Function GetObjectProp(Instance: TObject; const PropName: string; MinClass: TClass): TObject;
  924. begin
  925. Result:=GetObjectProp(Instance,FindPropInfo(Instance,PropName),MinClass);
  926. end;
  927. Function GetObjectProp(Instance: TObject; PropInfo : PPropInfo): TObject;
  928. begin
  929. Result:=GetObjectProp(Instance,PropInfo,Nil);
  930. end;
  931. Function GetObjectProp(Instance: TObject; PropInfo : PPropInfo; MinClass: TClass): TObject;
  932. begin
  933. {$ifdef cpu64}
  934. Result:=TObject(GetInt64Prop(Instance,PropInfo));
  935. {$else cpu64}
  936. Result:=TObject(PtrInt(GetOrdProp(Instance,PropInfo)));
  937. {$endif cpu64}
  938. If (MinClass<>Nil) and (Result<>Nil) Then
  939. If Not Result.InheritsFrom(MinClass) then
  940. Result:=Nil;
  941. end;
  942. Procedure SetObjectProp(Instance: TObject; const PropName: string; Value: TObject);
  943. begin
  944. SetObjectProp(Instance,FindPropInfo(Instance,PropName),Value);
  945. end;
  946. Procedure SetObjectProp(Instance: TObject; PropInfo : PPropInfo; Value: TObject);
  947. begin
  948. {$ifdef cpu64}
  949. SetInt64Prop(Instance,PropInfo,Int64(Value));
  950. {$else cpu64}
  951. SetOrdProp(Instance,PropInfo,Integer(Value));
  952. {$endif cpu64}
  953. end;
  954. Function GetObjectPropClass(Instance: TObject; const PropName: string): TClass;
  955. begin
  956. Result:=GetTypeData(FindPropInfo(Instance,PropName)^.PropType)^.ClassType;
  957. end;
  958. { ---------------------------------------------------------------------
  959. Interface wrapprers
  960. ---------------------------------------------------------------------}
  961. function GetInterfaceProp(Instance: TObject; const PropName: string): IInterface;
  962. begin
  963. Result:=GetInterfaceProp(Instance,FindPropInfo(Instance,PropName));
  964. end;
  965. function GetInterfaceProp(Instance: TObject; PropInfo: PPropInfo): IInterface;
  966. begin
  967. {$ifdef cpu64}
  968. Result:=IInterface(GetInt64Prop(Instance,PropInfo));
  969. {$else cpu64}
  970. Result:=IInterface(PtrInt(GetOrdProp(Instance,PropInfo)));
  971. {$endif cpu64}
  972. end;
  973. procedure SetInterfaceProp(Instance: TObject; const PropName: string; const Value: IInterface);
  974. begin
  975. SetInterfaceProp(Instance,FindPropInfo(Instance,PropName),Value);
  976. end;
  977. procedure SetInterfaceProp(Instance: TObject; PropInfo: PPropInfo; const Value: IInterface);
  978. type
  979. TSetIntfStrProcIndex=procedure(index:longint;const i:IInterface) of object;
  980. TSetIntfStrProc=procedure(i:IInterface) of object;
  981. var
  982. AMethod : TMethod;
  983. begin
  984. case Propinfo^.PropType^.Kind of
  985. tkInterface:
  986. begin
  987. case (PropInfo^.PropProcs shr 2) and 3 of
  988. ptField:
  989. PInterface(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  990. ptstatic,
  991. ptvirtual :
  992. begin
  993. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  994. AMethod.Code:=PropInfo^.SetProc
  995. else
  996. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  997. AMethod.Data:=Instance;
  998. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  999. TSetIntfStrProcIndex(AMethod)(PropInfo^.Index,Value)
  1000. else
  1001. TSetIntfStrProc(AMethod)(Value);
  1002. end;
  1003. end;
  1004. end;
  1005. end;
  1006. end;
  1007. { ---------------------------------------------------------------------
  1008. String properties
  1009. ---------------------------------------------------------------------}
  1010. Function GetStrProp(Instance: TObject; PropInfo: PPropInfo): AnsiString;
  1011. type
  1012. TGetShortStrProcIndex=function(index:longint):ShortString of object;
  1013. TGetShortStrProc=function():ShortString of object;
  1014. TGetAnsiStrProcIndex=function(index:longint):AnsiString of object;
  1015. TGetAnsiStrProc=function():AnsiString of object;
  1016. var
  1017. AMethod : TMethod;
  1018. begin
  1019. Result:='';
  1020. case Propinfo^.PropType^.Kind of
  1021. tkWString:
  1022. Result:=GetWideStrProp(Instance,PropInfo);
  1023. tkSString:
  1024. begin
  1025. case (PropInfo^.PropProcs) and 3 of
  1026. ptField:
  1027. Result := PShortString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  1028. ptstatic,
  1029. ptvirtual :
  1030. begin
  1031. if (PropInfo^.PropProcs and 3)=ptStatic then
  1032. AMethod.Code:=PropInfo^.GetProc
  1033. else
  1034. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1035. AMethod.Data:=Instance;
  1036. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1037. Result:=TGetShortStrProcIndex(AMethod)(PropInfo^.Index)
  1038. else
  1039. Result:=TGetShortStrProc(AMethod)();
  1040. end;
  1041. end;
  1042. end;
  1043. tkAString:
  1044. begin
  1045. case (PropInfo^.PropProcs) and 3 of
  1046. ptField:
  1047. Result := PAnsiString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  1048. ptstatic,
  1049. ptvirtual :
  1050. begin
  1051. if (PropInfo^.PropProcs and 3)=ptStatic then
  1052. AMethod.Code:=PropInfo^.GetProc
  1053. else
  1054. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1055. AMethod.Data:=Instance;
  1056. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1057. Result:=TGetAnsiStrProcIndex(AMethod)(PropInfo^.Index)
  1058. else
  1059. Result:=TGetAnsiStrProc(AMethod)();
  1060. end;
  1061. end;
  1062. end;
  1063. end;
  1064. end;
  1065. Procedure SetStrProp(Instance : TObject;PropInfo : PPropInfo; const Value : AnsiString);
  1066. type
  1067. TSetShortStrProcIndex=procedure(index:longint;const s:ShortString) of object;
  1068. TSetShortStrProc=procedure(const s:ShortString) of object;
  1069. TSetAnsiStrProcIndex=procedure(index:longint;s:AnsiString) of object;
  1070. TSetAnsiStrProc=procedure(s:AnsiString) of object;
  1071. var
  1072. AMethod : TMethod;
  1073. begin
  1074. case Propinfo^.PropType^.Kind of
  1075. tkWString:
  1076. SetWideStrProp(Instance,PropInfo,Value);
  1077. tkSString:
  1078. begin
  1079. case (PropInfo^.PropProcs shr 2) and 3 of
  1080. ptField:
  1081. PShortString(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  1082. ptstatic,
  1083. ptvirtual :
  1084. begin
  1085. if (PropInfo^.PropProcs and 3)=ptStatic then
  1086. AMethod.Code:=PropInfo^.SetProc
  1087. else
  1088. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1089. AMethod.Data:=Instance;
  1090. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1091. TSetShortStrProcIndex(AMethod)(PropInfo^.Index,Value)
  1092. else
  1093. TSetShortStrProc(AMethod)(Value);
  1094. end;
  1095. end;
  1096. end;
  1097. tkAString:
  1098. begin
  1099. case (PropInfo^.PropProcs shr 2) and 3 of
  1100. ptField:
  1101. PAnsiString(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  1102. ptstatic,
  1103. ptvirtual :
  1104. begin
  1105. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1106. AMethod.Code:=PropInfo^.SetProc
  1107. else
  1108. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1109. AMethod.Data:=Instance;
  1110. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1111. TSetAnsiStrProcIndex(AMethod)(PropInfo^.Index,Value)
  1112. else
  1113. TSetAnsiStrProc(AMethod)(Value);
  1114. end;
  1115. end;
  1116. end;
  1117. end;
  1118. end;
  1119. Function GetStrProp(Instance: TObject; const PropName: string): string;
  1120. begin
  1121. Result:=GetStrProp(Instance,FindPropInfo(Instance,PropName));
  1122. end;
  1123. Procedure SetStrProp(Instance: TObject; const PropName: string; const Value: AnsiString);
  1124. begin
  1125. SetStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  1126. end;
  1127. Function GetWideStrProp(Instance: TObject; const PropName: string): WideString;
  1128. begin
  1129. Result:=GetWideStrProp(Instance, FindPropInfo(Instance, PropName));
  1130. end;
  1131. procedure SetWideStrProp(Instance: TObject; const PropName: string; const Value: WideString);
  1132. begin
  1133. SetWideStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  1134. end;
  1135. Function GetWideStrProp(Instance: TObject; PropInfo: PPropInfo): WideString;
  1136. type
  1137. TGetWideStrProcIndex=function(index:longint):WideString of object;
  1138. TGetWideStrProc=function():WideString of object;
  1139. var
  1140. AMethod : TMethod;
  1141. begin
  1142. Result:='';
  1143. case Propinfo^.PropType^.Kind of
  1144. tkSString,tkAString:
  1145. Result:=GetStrProp(Instance,PropInfo);
  1146. tkWString:
  1147. begin
  1148. case (PropInfo^.PropProcs) and 3 of
  1149. ptField:
  1150. Result := PWideString(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1151. ptstatic,
  1152. ptvirtual :
  1153. begin
  1154. if (PropInfo^.PropProcs and 3)=ptStatic then
  1155. AMethod.Code:=PropInfo^.GetProc
  1156. else
  1157. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1158. AMethod.Data:=Instance;
  1159. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1160. Result:=TGetWideStrProcIndex(AMethod)(PropInfo^.Index)
  1161. else
  1162. Result:=TGetWideStrProc(AMethod)();
  1163. end;
  1164. end;
  1165. end;
  1166. end;
  1167. end;
  1168. Procedure SetWideStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: WideString);
  1169. type
  1170. TSetWideStrProcIndex=procedure(index:longint;s:WideString) of object;
  1171. TSetWideStrProc=procedure(s:WideString) of object;
  1172. var
  1173. AMethod : TMethod;
  1174. begin
  1175. case Propinfo^.PropType^.Kind of
  1176. tkSString,tkAString:
  1177. SetStrProp(Instance,PropInfo,Value);
  1178. tkWString:
  1179. begin
  1180. case (PropInfo^.PropProcs shr 2) and 3 of
  1181. ptField:
  1182. PWideString(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1183. ptstatic,
  1184. ptvirtual :
  1185. begin
  1186. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1187. AMethod.Code:=PropInfo^.SetProc
  1188. else
  1189. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1190. AMethod.Data:=Instance;
  1191. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1192. TSetWideStrProcIndex(AMethod)(PropInfo^.Index,Value)
  1193. else
  1194. TSetWideStrProc(AMethod)(Value);
  1195. end;
  1196. end;
  1197. end;
  1198. end;
  1199. end;
  1200. {$ifndef FPUNONE}
  1201. { ---------------------------------------------------------------------
  1202. Float properties
  1203. ---------------------------------------------------------------------}
  1204. function GetFloatProp(Instance : TObject;PropInfo : PPropInfo) : Extended;
  1205. type
  1206. TGetExtendedProc = function:Extended of object;
  1207. TGetExtendedProcIndex = function(Index: integer): Extended of object;
  1208. TGetDoubleProc = function:Double of object;
  1209. TGetDoubleProcIndex = function(Index: integer): Double of object;
  1210. TGetSingleProc = function:Single of object;
  1211. TGetSingleProcIndex = function(Index: integer):Single of object;
  1212. TGetCurrencyProc = function : Currency of object;
  1213. TGetCurrencyProcIndex = function(Index: integer) : Currency of object;
  1214. var
  1215. AMethod : TMethod;
  1216. begin
  1217. Result:=0.0;
  1218. case PropInfo^.PropProcs and 3 of
  1219. ptField:
  1220. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  1221. ftSingle:
  1222. Result:=PSingle(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1223. ftDouble:
  1224. Result:=PDouble(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1225. ftExtended:
  1226. Result:=PExtended(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1227. ftcomp:
  1228. Result:=PComp(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1229. ftcurr:
  1230. Result:=PCurrency(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1231. end;
  1232. ptStatic,
  1233. ptVirtual:
  1234. begin
  1235. if (PropInfo^.PropProcs and 3)=ptStatic then
  1236. AMethod.Code:=PropInfo^.GetProc
  1237. else
  1238. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1239. AMethod.Data:=Instance;
  1240. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  1241. ftSingle:
  1242. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  1243. Result:=TGetSingleProc(AMethod)()
  1244. else
  1245. Result:=TGetSingleProcIndex(AMethod)(PropInfo^.Index);
  1246. ftDouble:
  1247. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  1248. Result:=TGetDoubleProc(AMethod)()
  1249. else
  1250. Result:=TGetDoubleProcIndex(AMethod)(PropInfo^.Index);
  1251. ftExtended:
  1252. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  1253. Result:=TGetExtendedProc(AMethod)()
  1254. else
  1255. Result:=TGetExtendedProcIndex(AMethod)(PropInfo^.Index);
  1256. ftCurr:
  1257. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  1258. Result:=TGetCurrencyProc(AMethod)()
  1259. else
  1260. Result:=TGetCurrencyProcIndex(AMethod)(PropInfo^.Index);
  1261. end;
  1262. end;
  1263. end;
  1264. end;
  1265. Procedure SetFloatProp(Instance : TObject;PropInfo : PPropInfo; Value : Extended);
  1266. type
  1267. TSetExtendedProc = procedure(const AValue: Extended) of object;
  1268. TSetExtendedProcIndex = procedure(Index: integer; AValue: Extended) of object;
  1269. TSetDoubleProc = procedure(const AValue: Double) of object;
  1270. TSetDoubleProcIndex = procedure(Index: integer; AValue: Double) of object;
  1271. TSetSingleProc = procedure(const AValue: Single) of object;
  1272. TSetSingleProcIndex = procedure(Index: integer; AValue: Single) of object;
  1273. TSetCurrencyProc = procedure(const AValue: Currency) of object;
  1274. TSetCurrencyProcIndex = procedure(Index: integer; AValue: Currency) of object;
  1275. Var
  1276. AMethod : TMethod;
  1277. begin
  1278. case (PropInfo^.PropProcs shr 2) and 3 of
  1279. ptfield:
  1280. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  1281. ftSingle:
  1282. PSingle(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1283. ftDouble:
  1284. PDouble(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1285. ftExtended:
  1286. PExtended(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1287. {$ifdef FPC_COMP_IS_INT64}
  1288. ftComp:
  1289. PComp(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=trunc(Value);
  1290. {$else FPC_COMP_IS_INT64}
  1291. ftComp:
  1292. PComp(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Comp(Value);
  1293. {$endif FPC_COMP_IS_INT64}
  1294. ftCurr:
  1295. PCurrency(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1296. end;
  1297. ptStatic,
  1298. ptVirtual:
  1299. begin
  1300. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1301. AMethod.Code:=PropInfo^.SetProc
  1302. else
  1303. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1304. AMethod.Data:=Instance;
  1305. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  1306. ftSingle:
  1307. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  1308. TSetSingleProc(AMethod)(Value)
  1309. else
  1310. TSetSingleProcIndex(AMethod)(PropInfo^.Index,Value);
  1311. ftDouble:
  1312. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  1313. TSetDoubleProc(AMethod)(Value)
  1314. else
  1315. TSetDoubleProcIndex(AMethod)(PropInfo^.Index,Value);
  1316. ftExtended:
  1317. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  1318. TSetExtendedProc(AMethod)(Value)
  1319. else
  1320. TSetExtendedProcIndex(AMethod)(PropInfo^.Index,Value);
  1321. ftCurr:
  1322. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  1323. TSetCurrencyProc(AMethod)(Value)
  1324. else
  1325. TSetCurrencyProcIndex(AMethod)(PropInfo^.Index,Value);
  1326. end;
  1327. end;
  1328. end;
  1329. end;
  1330. function GetFloatProp(Instance: TObject; const PropName: string): Extended;
  1331. begin
  1332. Result:=GetFloatProp(Instance,FindPropInfo(Instance,PropName))
  1333. end;
  1334. Procedure SetFloatProp(Instance: TObject; const PropName: string; Value: Extended);
  1335. begin
  1336. SetFloatProp(Instance,FindPropInfo(Instance,PropName),Value);
  1337. end;
  1338. {$endif}
  1339. { ---------------------------------------------------------------------
  1340. Method properties
  1341. ---------------------------------------------------------------------}
  1342. Function GetMethodProp(Instance : TObject;PropInfo : PPropInfo) : TMethod;
  1343. type
  1344. TGetMethodProcIndex=function(Index: Longint): TMethod of object;
  1345. TGetMethodProc=function(): TMethod of object;
  1346. var
  1347. value: PMethod;
  1348. AMethod : TMethod;
  1349. begin
  1350. Result.Code:=nil;
  1351. Result.Data:=nil;
  1352. case (PropInfo^.PropProcs) and 3 of
  1353. ptfield:
  1354. begin
  1355. Value:=PMethod(Pointer(Instance)+PtrUInt(PropInfo^.GetProc));
  1356. if Value<>nil then
  1357. Result:=Value^;
  1358. end;
  1359. ptstatic,
  1360. ptvirtual :
  1361. begin
  1362. if (PropInfo^.PropProcs and 3)=ptStatic then
  1363. AMethod.Code:=PropInfo^.GetProc
  1364. else
  1365. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1366. AMethod.Data:=Instance;
  1367. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1368. Result:=TGetMethodProcIndex(AMethod)(PropInfo^.Index)
  1369. else
  1370. Result:=TGetMethodProc(AMethod)();
  1371. end;
  1372. end;
  1373. end;
  1374. Procedure SetMethodProp(Instance : TObject;PropInfo : PPropInfo; const Value : TMethod);
  1375. type
  1376. TSetMethodProcIndex=procedure(index:longint;p:TMethod) of object;
  1377. TSetMethodProc=procedure(p:TMethod) of object;
  1378. var
  1379. AMethod : TMethod;
  1380. begin
  1381. case (PropInfo^.PropProcs shr 2) and 3 of
  1382. ptfield:
  1383. PMethod(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^ := Value;
  1384. ptstatic,
  1385. ptvirtual :
  1386. begin
  1387. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1388. AMethod.Code:=PropInfo^.SetProc
  1389. else
  1390. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1391. AMethod.Data:=Instance;
  1392. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1393. TSetMethodProcIndex(AMethod)(PropInfo^.Index,Value)
  1394. else
  1395. TSetMethodProc(AMethod)(Value);
  1396. end;
  1397. end;
  1398. end;
  1399. Function GetMethodProp(Instance: TObject; const PropName: string): TMethod;
  1400. begin
  1401. Result:=GetMethodProp(Instance,FindPropInfo(Instance,PropName));
  1402. end;
  1403. Procedure SetMethodProp(Instance: TObject; const PropName: string; const Value: TMethod);
  1404. begin
  1405. SetMethodProp(Instance,FindPropInfo(Instance,PropName),Value);
  1406. end;
  1407. { ---------------------------------------------------------------------
  1408. Variant properties
  1409. ---------------------------------------------------------------------}
  1410. Procedure CheckVariantEvent(P : Pointer);
  1411. begin
  1412. If (P=Nil) then
  1413. Raise Exception.Create(SErrNoVariantSupport);
  1414. end;
  1415. Function GetVariantProp(Instance : TObject;PropInfo : PPropInfo): Variant;
  1416. begin
  1417. CheckVariantEvent(Pointer(OnGetVariantProp));
  1418. Result:=OnGetVariantProp(Instance,PropInfo);
  1419. end;
  1420. Procedure SetVariantProp(Instance : TObject;PropInfo : PPropInfo; const Value: Variant);
  1421. begin
  1422. CheckVariantEvent(Pointer(OnSetVariantProp));
  1423. OnSetVariantProp(Instance,PropInfo,Value);
  1424. end;
  1425. Function GetVariantProp(Instance: TObject; const PropName: string): Variant;
  1426. begin
  1427. Result:=GetVariantProp(Instance,FindPropInfo(Instance,PropName));
  1428. end;
  1429. Procedure SetVariantProp(Instance: TObject; const PropName: string; const Value: Variant);
  1430. begin
  1431. SetVariantprop(instance,FindpropInfo(Instance,PropName),Value);
  1432. end;
  1433. { ---------------------------------------------------------------------
  1434. All properties through variant.
  1435. ---------------------------------------------------------------------}
  1436. Function GetPropValue(Instance: TObject; const PropName: string): Variant;
  1437. begin
  1438. Result:=GetPropValue(Instance,PropName,True);
  1439. end;
  1440. Function GetPropValue(Instance: TObject; const PropName: string; PreferStrings: Boolean): Variant;
  1441. begin
  1442. CheckVariantEvent(Pointer(OnGetPropValue));
  1443. Result:=OnGetPropValue(Instance,PropName,PreferStrings)
  1444. end;
  1445. Procedure SetPropValue(Instance: TObject; const PropName: string; const Value: Variant);
  1446. begin
  1447. CheckVariantEvent(Pointer(OnSetPropValue));
  1448. OnSetPropValue(Instance,PropName,Value);
  1449. end;
  1450. { ---------------------------------------------------------------------
  1451. Easy access methods that appeared in Delphi 5
  1452. ---------------------------------------------------------------------}
  1453. Function IsPublishedProp(Instance: TObject; const PropName: string): Boolean;
  1454. begin
  1455. Result:=GetPropInfo(Instance,PropName)<>Nil;
  1456. end;
  1457. Function IsPublishedProp(AClass: TClass; const PropName: string): Boolean;
  1458. begin
  1459. Result:=GetPropInfo(AClass,PropName)<>Nil;
  1460. end;
  1461. Function PropIsType(Instance: TObject; const PropName: string; TypeKind: TTypeKind): Boolean;
  1462. begin
  1463. Result:=FindPropInfo(Instance,PropName)^.PropType^.Kind=TypeKind
  1464. end;
  1465. Function PropIsType(AClass: TClass; const PropName: string; TypeKind: TTypeKind): Boolean;
  1466. begin
  1467. Result:=PropType(AClass,PropName)=TypeKind
  1468. end;
  1469. Function PropType(Instance: TObject; const PropName: string): TTypeKind;
  1470. begin
  1471. Result:=FindPropInfo(Instance,PropName)^.PropType^.Kind;
  1472. end;
  1473. Function PropType(AClass: TClass; const PropName: string): TTypeKind;
  1474. begin
  1475. Result:=FindPropInfo(AClass,PropName)^.PropType^.Kind;
  1476. end;
  1477. Function IsStoredProp(Instance: TObject; const PropName: string): Boolean;
  1478. begin
  1479. Result:=IsStoredProp(instance,FindPropInfo(Instance,PropName));
  1480. end;
  1481. end.