typinfo.pp 56 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819
  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,tkProcVar,tkUString,tkUChar);
  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,tkUString:
  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. Function GetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo): UnicodeString;
  216. Function GetUnicodeStrProp(Instance: TObject; const PropName: string): UnicodeString;
  217. Procedure SetUnicodeStrProp(Instance: TObject; const PropName: string; const Value: UnicodeString);
  218. Procedure SetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: UnicodeString);
  219. {$ifndef FPUNONE}
  220. Function GetFloatProp(Instance: TObject; PropInfo : PPropInfo) : Extended;
  221. Function GetFloatProp(Instance: TObject; const PropName: string): Extended;
  222. Procedure SetFloatProp(Instance: TObject; const PropName: string; Value: Extended);
  223. Procedure SetFloatProp(Instance: TObject; PropInfo : PPropInfo; Value : Extended);
  224. {$endif}
  225. Function GetObjectProp(Instance: TObject; const PropName: string): TObject;
  226. Function GetObjectProp(Instance: TObject; const PropName: string; MinClass: TClass): TObject;
  227. Function GetObjectProp(Instance: TObject; PropInfo: PPropInfo): TObject;
  228. Function GetObjectProp(Instance: TObject; PropInfo: PPropInfo; MinClass: TClass): TObject;
  229. Procedure SetObjectProp(Instance: TObject; const PropName: string; Value: TObject);
  230. Procedure SetObjectProp(Instance: TObject; PropInfo: PPropInfo; Value: TObject);
  231. Function GetObjectPropClass(Instance: TObject; const PropName: string): TClass;
  232. Function GetMethodProp(Instance: TObject; PropInfo: PPropInfo) : TMethod;
  233. Function GetMethodProp(Instance: TObject; const PropName: string): TMethod;
  234. Procedure SetMethodProp(Instance: TObject; PropInfo: PPropInfo; const Value : TMethod);
  235. Procedure SetMethodProp(Instance: TObject; const PropName: string; const Value: TMethod);
  236. Function GetInt64Prop(Instance: TObject; PropInfo: PPropInfo): Int64;
  237. Function GetInt64Prop(Instance: TObject; const PropName: string): Int64;
  238. Procedure SetInt64Prop(Instance: TObject; PropInfo: PPropInfo; const Value: Int64);
  239. Procedure SetInt64Prop(Instance: TObject; const PropName: string; const Value: Int64);
  240. Function GetPropValue(Instance: TObject; const PropName: string): Variant;
  241. Function GetPropValue(Instance: TObject; const PropName: string; PreferStrings: Boolean): Variant;
  242. Procedure SetPropValue(Instance: TObject; const PropName: string; const Value: Variant);
  243. Function GetVariantProp(Instance: TObject; PropInfo : PPropInfo): Variant;
  244. Function GetVariantProp(Instance: TObject; const PropName: string): Variant;
  245. Procedure SetVariantProp(Instance: TObject; const PropName: string; const Value: Variant);
  246. Procedure SetVariantProp(Instance: TObject; PropInfo : PPropInfo; const Value: Variant);
  247. function GetInterfaceProp(Instance: TObject; const PropName: string): IInterface;
  248. function GetInterfaceProp(Instance: TObject; PropInfo: PPropInfo): IInterface;
  249. procedure SetInterfaceProp(Instance: TObject; const PropName: string; const Value: IInterface);
  250. procedure SetInterfaceProp(Instance: TObject; PropInfo: PPropInfo; const Value: IInterface);
  251. // Auxiliary routines, which may be useful
  252. Function GetEnumName(TypeInfo : PTypeInfo;Value : Integer) : string;
  253. Function GetEnumValue(TypeInfo : PTypeInfo;const Name : string) : Integer;
  254. function GetEnumNameCount(enum1: PTypeInfo): SizeInt;
  255. function SetToString(TypeInfo: PTypeInfo; Value: Integer; Brackets: Boolean) : String;
  256. function SetToString(PropInfo: PPropInfo; Value: Integer; Brackets: Boolean) : String;
  257. function SetToString(PropInfo: PPropInfo; Value: Integer) : String;
  258. function StringToSet(PropInfo: PPropInfo; const Value: string): Integer;
  259. function StringToSet(TypeInfo: PTypeInfo; const Value: string): Integer;
  260. const
  261. BooleanIdents: array[Boolean] of String = ('False', 'True');
  262. DotSep: String = '.';
  263. Type
  264. EPropertyError = Class(Exception);
  265. TGetPropValue = Function (Instance: TObject; const PropName: string; PreferStrings: Boolean) : Variant;
  266. TSetPropValue = Procedure (Instance: TObject; const PropName: string; const Value: Variant);
  267. TGetVariantProp = Function (Instance: TObject; PropInfo : PPropInfo): Variant;
  268. TSetVariantProp = Procedure (Instance: TObject; PropInfo : PPropInfo; const Value: Variant);
  269. EPropertyConvertError = class(Exception); // Not used (yet), but defined for compatibility.
  270. Const
  271. OnGetPropValue : TGetPropValue = Nil;
  272. OnSetPropValue : TSetPropValue = Nil;
  273. OnGetVariantprop : TGetVariantProp = Nil;
  274. OnSetVariantprop : TSetVariantProp = Nil;
  275. Implementation
  276. uses rtlconsts;
  277. type
  278. PMethod = ^TMethod;
  279. { ---------------------------------------------------------------------
  280. Auxiliary methods
  281. ---------------------------------------------------------------------}
  282. function aligntoptr(p : pointer) : pointer;inline;
  283. begin
  284. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  285. result:=align(p,sizeof(p));
  286. {$else FPC_REQUIRES_PROPER_ALIGNMENT}
  287. result:=p;
  288. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  289. end;
  290. Function GetEnumName(TypeInfo : PTypeInfo;Value : Integer) : string;
  291. Var PS : PShortString;
  292. PT : PTypeData;
  293. begin
  294. PT:=GetTypeData(TypeInfo);
  295. if TypeInfo^.Kind=tkBool then
  296. begin
  297. case Value of
  298. 0,1:
  299. Result:=BooleanIdents[Boolean(Value)];
  300. else
  301. Result:='';
  302. end;
  303. end
  304. else
  305. begin
  306. PS:=@PT^.NameList;
  307. While Value>0 Do
  308. begin
  309. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  310. Dec(Value);
  311. end;
  312. Result:=PS^;
  313. end;
  314. end;
  315. Function GetEnumValue(TypeInfo : PTypeInfo;const Name : string) : Integer;
  316. Var PS : PShortString;
  317. PT : PTypeData;
  318. Count : longint;
  319. sName: shortstring;
  320. begin
  321. If Length(Name)=0 then
  322. exit(-1);
  323. sName := Name;
  324. PT:=GetTypeData(TypeInfo);
  325. Count:=0;
  326. Result:=-1;
  327. if TypeInfo^.Kind=tkBool then
  328. begin
  329. If CompareText(BooleanIdents[false],Name)=0 then
  330. result:=0
  331. else if CompareText(BooleanIdents[true],Name)=0 then
  332. result:=1;
  333. end
  334. else
  335. begin
  336. PS:=@PT^.NameList;
  337. While (Result=-1) and (PByte(PS)^<>0) do
  338. begin
  339. If ShortCompareText(PS^, sName) = 0 then
  340. Result:=Count;
  341. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  342. Inc(Count);
  343. end;
  344. end;
  345. end;
  346. function GetEnumNameCount(enum1: PTypeInfo): SizeInt;
  347. var
  348. PS: PShortString;
  349. PT: PTypeData;
  350. Count: SizeInt;
  351. begin
  352. PT:=GetTypeData(enum1);
  353. if enum1^.Kind=tkBool then
  354. Result:=2
  355. else
  356. begin
  357. Count:=0;
  358. Result:=0;
  359. PS:=@PT^.NameList;
  360. While (PByte(PS)^<>0) do
  361. begin
  362. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  363. Inc(Count);
  364. end;
  365. Result := Count;
  366. end;
  367. end;
  368. Function SetToString(PropInfo: PPropInfo; Value: Integer; Brackets: Boolean) : String;
  369. begin
  370. Result:=SetToString(PropInfo^.PropType,Value,Brackets);
  371. end;
  372. Function SetToString(TypeInfo: PTypeInfo; Value: Integer; Brackets: Boolean) : String;
  373. {$ifdef FPC_NEW_BIGENDIAN_SETS}
  374. type
  375. tsetarr = bitpacked array[0..31] of 0..1;
  376. {$endif}
  377. Var
  378. I : Integer;
  379. PTI : PTypeInfo;
  380. begin
  381. {$if defined(FPC_NEW_BIGENDIAN_SETS) and defined(FPC_BIG_ENDIAN)}
  382. case GetTypeData(TypeInfo)^.OrdType of
  383. otSByte,otUByte: Value:=Value shl 24;
  384. otSWord,otUWord: Value:=Value shl 16;
  385. end;
  386. {$endif}
  387. PTI:=GetTypeData(TypeInfo)^.CompType;
  388. Result:='';
  389. For I:=0 to SizeOf(Integer)*8-1 do
  390. begin
  391. {$ifdef FPC_NEW_BIGENDIAN_SETS}
  392. if (tsetarr(Value)[i]<>0) then
  393. {$else}
  394. if ((Value and 1)<>0) then
  395. {$endif}
  396. begin
  397. If Result='' then
  398. Result:=GetEnumName(PTI,i)
  399. else
  400. Result:=Result+','+GetEnumName(PTI,I);
  401. end;
  402. {$ifndef FPC_NEW_BIGENDIAN_SETS}
  403. Value:=Value shr 1;
  404. {$endif FPC_NEW_BIGENDIAN_SETS}
  405. end;
  406. if Brackets then
  407. Result:='['+Result+']';
  408. end;
  409. Function SetToString(PropInfo: PPropInfo; Value: Integer) : String;
  410. begin
  411. Result:=SetToString(PropInfo,Value,False);
  412. end;
  413. Const
  414. SetDelim = ['[',']',',',' '];
  415. Function GetNextElement(Var S : String) : String;
  416. Var
  417. J : Integer;
  418. begin
  419. J:=1;
  420. Result:='';
  421. If Length(S)>0 then
  422. begin
  423. While (J<=Length(S)) and Not (S[j] in SetDelim) do
  424. Inc(j);
  425. Result:=Copy(S,1,j-1);
  426. Delete(S,1,j);
  427. end;
  428. end;
  429. Function StringToSet(PropInfo: PPropInfo; const Value: string): Integer;
  430. begin
  431. Result:=StringToSet(PropInfo^.PropType,Value);
  432. end;
  433. Function StringToSet(TypeInfo: PTypeInfo; const Value: string): Integer;
  434. Var
  435. S,T : String;
  436. I : Integer;
  437. PTI : PTypeInfo;
  438. begin
  439. Result:=0;
  440. PTI:=GetTypeData(TypeInfo)^.Comptype;
  441. S:=Value;
  442. I:=1;
  443. If Length(S)>0 then
  444. begin
  445. While (I<=Length(S)) and (S[i] in SetDelim) do
  446. Inc(I);
  447. Delete(S,1,i-1);
  448. end;
  449. While (S<>'') do
  450. begin
  451. T:=GetNextElement(S);
  452. if T<>'' then
  453. begin
  454. I:=GetEnumValue(PTI,T);
  455. if (I<0) then
  456. raise EPropertyError.CreateFmt(SErrUnknownEnumValue, [T]);
  457. Result:=Result or (1 shl i);
  458. end;
  459. end;
  460. end;
  461. Function GetTypeData(TypeInfo : PTypeInfo) : PTypeData;
  462. begin
  463. GetTypeData:=PTypeData(aligntoptr(PTypeData(pointer(TypeInfo)+2+PByte(pointer(TypeInfo)+1)^)));
  464. end;
  465. { ---------------------------------------------------------------------
  466. Basic Type information functions.
  467. ---------------------------------------------------------------------}
  468. Function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string) : PPropInfo;
  469. var
  470. hp : PTypeData;
  471. i : longint;
  472. p : shortstring;
  473. pd : ^TPropData;
  474. begin
  475. P:=PropName; // avoid Ansi<->short conversion in a loop
  476. while Assigned(TypeInfo) do
  477. begin
  478. // skip the name
  479. hp:=GetTypeData(Typeinfo);
  480. // the class info rtti the property rtti follows immediatly
  481. pd:=aligntoptr(pointer(pointer(@hp^.UnitName)+Length(hp^.UnitName)+1));
  482. Result:=PPropInfo(@pd^.PropList);
  483. for i:=1 to pd^.PropCount do
  484. begin
  485. // found a property of that name ?
  486. if ShortCompareText(Result^.Name, P) = 0 then
  487. exit;
  488. // skip to next property
  489. Result:=PPropInfo(aligntoptr(pointer(@Result^.Name)+byte(Result^.Name[0])+1));
  490. end;
  491. // parent class
  492. Typeinfo:=hp^.ParentInfo;
  493. end;
  494. Result:=Nil;
  495. end;
  496. Function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string; Akinds : TTypeKinds) : PPropInfo;
  497. begin
  498. Result:=GetPropInfo(TypeInfo,PropName);
  499. If (Akinds<>[]) then
  500. If (Result<>Nil) then
  501. If Not (Result^.PropType^.Kind in AKinds) then
  502. Result:=Nil;
  503. end;
  504. Function GetPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds) : PPropInfo;
  505. begin
  506. Result:=GetPropInfo(PTypeInfo(AClass.ClassInfo),PropName,AKinds);
  507. end;
  508. Function GetPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds) : PPropInfo;
  509. begin
  510. Result:=GetPropInfo(Instance.ClassType,PropName,AKinds);
  511. end;
  512. Function GetPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  513. begin
  514. Result:=GetPropInfo(Instance,PropName,[]);
  515. end;
  516. Function GetPropInfo(AClass: TClass; const PropName: string): PPropInfo;
  517. begin
  518. Result:=GetPropInfo(AClass,PropName,[]);
  519. end;
  520. Function FindPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  521. begin
  522. result:=GetPropInfo(Instance, PropName);
  523. if Result=nil then
  524. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  525. end;
  526. Function FindPropInfo(AClass:TClass;const PropName: string): PPropInfo;
  527. begin
  528. result:=GetPropInfo(AClass,PropName);
  529. if result=nil then
  530. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  531. end;
  532. Function IsStoredProp(Instance : TObject;PropInfo : PPropInfo) : Boolean;
  533. type
  534. TBooleanIndexFunc=function(Index:integer):boolean of object;
  535. TBooleanFunc=function:boolean of object;
  536. var
  537. AMethod : TMethod;
  538. begin
  539. case (PropInfo^.PropProcs shr 4) and 3 of
  540. ptfield:
  541. Result:=PBoolean(Pointer(Instance)+PtrUInt(PropInfo^.StoredProc))^;
  542. ptconst:
  543. Result:=LongBool(PropInfo^.StoredProc);
  544. ptstatic,
  545. ptvirtual:
  546. begin
  547. if (PropInfo^.PropProcs shr 4) and 3=ptstatic then
  548. AMethod.Code:=PropInfo^.StoredProc
  549. else
  550. AMethod.Code:=ppointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.StoredProc))^;
  551. AMethod.Data:=Instance;
  552. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  553. Result:=TBooleanIndexFunc(AMethod)(PropInfo^.Index)
  554. else
  555. Result:=TBooleanFunc(AMethod)();
  556. end;
  557. end;
  558. end;
  559. Procedure GetPropInfos(TypeInfo : PTypeInfo;PropList : PPropList);
  560. {
  561. Store Pointers to property information in the list pointed
  562. to by proplist. PRopList must contain enough space to hold ALL
  563. properties.
  564. }
  565. Var
  566. TD : PTypeData;
  567. TP : PPropInfo;
  568. Count : Longint;
  569. begin
  570. // Get this objects TOTAL published properties count
  571. TD:=GetTypeData(TypeInfo);
  572. // Clear list
  573. FillChar(PropList^,TD^.PropCount*sizeof(Pointer),0);
  574. repeat
  575. TD:=GetTypeData(TypeInfo);
  576. // published properties count for this object
  577. TP:=aligntoptr(PPropInfo(aligntoptr((Pointer(@TD^.UnitName)+Length(TD^.UnitName)+1))));
  578. Count:=PWord(TP)^;
  579. // Now point TP to first propinfo record.
  580. Inc(Pointer(TP),SizeOF(Word));
  581. tp:=aligntoptr(tp);
  582. While Count>0 do
  583. begin
  584. // Don't overwrite properties with the same name
  585. if PropList^[TP^.NameIndex]=nil then
  586. PropList^[TP^.NameIndex]:=TP;
  587. // Point to TP next propinfo record.
  588. // Located at Name[Length(Name)+1] !
  589. TP:=aligntoptr(PPropInfo(pointer(@TP^.Name)+PByte(@TP^.Name)^+1));
  590. Dec(Count);
  591. end;
  592. TypeInfo:=TD^.Parentinfo;
  593. until TypeInfo=nil;
  594. end;
  595. Procedure InsertProp (PL : PProplist;PI : PPropInfo; Count : longint);
  596. Var
  597. I : Longint;
  598. begin
  599. I:=0;
  600. While (I<Count) and (PI^.Name>PL^[I]^.Name) do
  601. Inc(I);
  602. If I<Count then
  603. Move(PL^[I], PL^[I+1], (Count - I) * SizeOf(Pointer));
  604. PL^[I]:=PI;
  605. end;
  606. Procedure InsertPropnosort (PL : PProplist;PI : PPropInfo; Count : longint);
  607. begin
  608. PL^[Count]:=PI;
  609. end;
  610. Type TInsertProp = Procedure (PL : PProplist;PI : PPropInfo; Count : longint);
  611. //Const InsertProps : array[false..boolean] of TInsertProp = (InsertPropNoSort,InsertProp);
  612. Function GetPropList(TypeInfo : PTypeInfo;TypeKinds : TTypeKinds; PropList : PPropList;Sorted : boolean = true):longint;
  613. {
  614. Store Pointers to property information OF A CERTAIN KIND in the list pointed
  615. to by proplist. PRopList must contain enough space to hold ALL
  616. properties.
  617. }
  618. Var
  619. TempList : PPropList;
  620. PropInfo : PPropinfo;
  621. I,Count : longint;
  622. DoInsertProp : TInsertProp;
  623. begin
  624. if sorted then
  625. DoInsertProp:=@InsertProp
  626. else
  627. DoInsertProp:=@InsertPropnosort;
  628. Result:=0;
  629. Count:=GetTypeData(TypeInfo)^.Propcount;
  630. If Count>0 then
  631. begin
  632. GetMem(TempList,Count*SizeOf(Pointer));
  633. Try
  634. GetPropInfos(TypeInfo,TempList);
  635. For I:=0 to Count-1 do
  636. begin
  637. PropInfo:=TempList^[i];
  638. If PropInfo^.PropType^.Kind in TypeKinds then
  639. begin
  640. If (PropList<>Nil) then
  641. DoInsertProp(PropList,PropInfo,Result);
  642. Inc(Result);
  643. end;
  644. end;
  645. finally
  646. FreeMem(TempList,Count*SizeOf(Pointer));
  647. end;
  648. end;
  649. end;
  650. Function GetPropList(TypeInfo: PTypeInfo; out PropList: PPropList): SizeInt;
  651. begin
  652. result:=GetTypeData(TypeInfo)^.Propcount;
  653. if result>0 then
  654. begin
  655. getmem(PropList,result*sizeof(pointer));
  656. GetPropInfos(TypeInfo,PropList);
  657. end
  658. else
  659. PropList:=Nil;
  660. end;
  661. function GetPropList(AObject: TObject; out PropList: PPropList): Integer;
  662. begin
  663. Result := GetPropList(PTypeInfo(AObject.ClassInfo), PropList);
  664. end;
  665. { ---------------------------------------------------------------------
  666. Property access functions
  667. ---------------------------------------------------------------------}
  668. { ---------------------------------------------------------------------
  669. Ordinal properties
  670. ---------------------------------------------------------------------}
  671. Function GetOrdProp(Instance : TObject;PropInfo : PPropInfo) : Int64;
  672. type
  673. TGetInt64ProcIndex=function(index:longint):Int64 of object;
  674. TGetInt64Proc=function():Int64 of object;
  675. TGetIntegerProcIndex=function(index:longint):longint of object;
  676. TGetIntegerProc=function:longint of object;
  677. TGetWordProcIndex=function(index:longint):word of object;
  678. TGetWordProc=function:word of object;
  679. TGetByteProcIndex=function(index:longint):Byte of object;
  680. TGetByteProc=function:Byte of object;
  681. var
  682. TypeInfo: PTypeInfo;
  683. AMethod : TMethod;
  684. DataSize: Integer;
  685. OrdType: TOrdType;
  686. Signed: Boolean;
  687. begin
  688. Result:=0;
  689. TypeInfo := PropInfo^.PropType;
  690. Signed := false;
  691. DataSize := 4;
  692. case TypeInfo^.Kind of
  693. {$ifdef cpu64}
  694. tkInterface,
  695. tkInterfaceRaw,
  696. tkDynArray,
  697. tkClass:
  698. DataSize:=8;
  699. {$endif cpu64}
  700. tkChar, tkBool:
  701. DataSize:=1;
  702. tkWChar:
  703. DataSize:=2;
  704. tkSet,
  705. tkEnumeration,
  706. tkInteger:
  707. begin
  708. OrdType:=GetTypeData(TypeInfo)^.OrdType;
  709. case OrdType of
  710. otSByte,otUByte: DataSize := 1;
  711. otSWord,otUWord: DataSize := 2;
  712. end;
  713. Signed := OrdType in [otSByte,otSWord,otSLong];
  714. end;
  715. tkInt64 :
  716. begin
  717. DataSize:=8;
  718. Signed:=true;
  719. end;
  720. tkQword :
  721. begin
  722. DataSize:=8;
  723. Signed:=false;
  724. end;
  725. end;
  726. case (PropInfo^.PropProcs) and 3 of
  727. ptfield:
  728. if Signed then begin
  729. case DataSize of
  730. 1: Result:=PShortInt(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  731. 2: Result:=PSmallInt(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  732. 4: Result:=PLongint(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  733. 8: Result:=PInt64(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  734. end;
  735. end else begin
  736. case DataSize of
  737. 1: Result:=PByte(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  738. 2: Result:=PWord(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  739. 4: Result:=PLongint(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  740. 8: Result:=PInt64(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  741. end;
  742. end;
  743. ptstatic,
  744. ptvirtual :
  745. begin
  746. if (PropInfo^.PropProcs and 3)=ptStatic then
  747. AMethod.Code:=PropInfo^.GetProc
  748. else
  749. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  750. AMethod.Data:=Instance;
  751. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then begin
  752. case DataSize of
  753. 1: Result:=TGetByteProcIndex(AMethod)(PropInfo^.Index);
  754. 2: Result:=TGetWordProcIndex(AMethod)(PropInfo^.Index);
  755. 4: Result:=TGetIntegerProcIndex(AMethod)(PropInfo^.Index);
  756. 8: result:=TGetInt64ProcIndex(AMethod)(PropInfo^.Index)
  757. end;
  758. end else begin
  759. case DataSize of
  760. 1: Result:=TGetByteProc(AMethod)();
  761. 2: Result:=TGetWordProc(AMethod)();
  762. 4: Result:=TGetIntegerProc(AMethod)();
  763. 8: result:=TGetInt64Proc(AMethod)();
  764. end;
  765. end;
  766. if Signed then begin
  767. case DataSize of
  768. 1: Result:=ShortInt(Result);
  769. 2: Result:=SmallInt(Result);
  770. end;
  771. end;
  772. end;
  773. end;
  774. end;
  775. Procedure SetOrdProp(Instance : TObject;PropInfo : PPropInfo;Value : Int64);
  776. type
  777. TSetInt64ProcIndex=procedure(index:longint;i:Int64) of object;
  778. TSetInt64Proc=procedure(i:Int64) of object;
  779. TSetIntegerProcIndex=procedure(index,i:longint) of object;
  780. TSetIntegerProc=procedure(i:longint) of object;
  781. var
  782. DataSize: Integer;
  783. AMethod : TMethod;
  784. begin
  785. if PropInfo^.PropType^.Kind in [tkInt64,tkQword
  786. { why do we have to handle classes here, see also below? (FK) }
  787. {$ifdef cpu64}
  788. ,tkInterface
  789. ,tkInterfaceRaw
  790. ,tkDynArray
  791. ,tkClass
  792. {$endif cpu64}
  793. ] then
  794. DataSize := 8
  795. else
  796. DataSize := 4;
  797. if not(PropInfo^.PropType^.Kind in [tkInt64,tkQword,tkClass]) then
  798. begin
  799. { cut off unnecessary stuff }
  800. case GetTypeData(PropInfo^.PropType)^.OrdType of
  801. otSWord,otUWord:
  802. begin
  803. Value:=Value and $ffff;
  804. DataSize := 2;
  805. end;
  806. otSByte,otUByte:
  807. begin
  808. Value:=Value and $ff;
  809. DataSize := 1;
  810. end;
  811. end;
  812. end;
  813. case (PropInfo^.PropProcs shr 2) and 3 of
  814. ptfield:
  815. case DataSize of
  816. 1: PByte(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Byte(Value);
  817. 2: PWord(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Word(Value);
  818. 4: PLongint(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Longint(Value);
  819. 8: PInt64(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  820. end;
  821. ptstatic,
  822. ptvirtual :
  823. begin
  824. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  825. AMethod.Code:=PropInfo^.SetProc
  826. else
  827. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  828. AMethod.Data:=Instance;
  829. if datasize=8 then
  830. begin
  831. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  832. TSetInt64ProcIndex(AMethod)(PropInfo^.Index,Value)
  833. else
  834. TSetInt64Proc(AMethod)(Value);
  835. end
  836. else
  837. begin
  838. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  839. TSetIntegerProcIndex(AMethod)(PropInfo^.Index,Value)
  840. else
  841. TSetIntegerProc(AMethod)(Value);
  842. end;
  843. end;
  844. end;
  845. end;
  846. Function GetOrdProp(Instance: TObject; const PropName: string): Int64;
  847. begin
  848. Result:=GetOrdProp(Instance,FindPropInfo(Instance,PropName));
  849. end;
  850. Procedure SetOrdProp(Instance: TObject; const PropName: string; Value: Int64);
  851. begin
  852. SetOrdProp(Instance,FindPropInfo(Instance,PropName),Value);
  853. end;
  854. Function GetEnumProp(Instance: TObject; Const PropInfo: PPropInfo): string;
  855. begin
  856. Result:=GetEnumName(PropInfo^.PropType, GetOrdProp(Instance, PropInfo));
  857. end;
  858. Function GetEnumProp(Instance: TObject; const PropName: string): string;
  859. begin
  860. Result:=GetEnumProp(Instance,FindPropInfo(Instance,PropName));
  861. end;
  862. Procedure SetEnumProp(Instance: TObject; const PropName: string; const Value: string);
  863. begin
  864. SetEnumProp(Instance,FindPropInfo(Instance,PropName),Value);
  865. end;
  866. Procedure SetEnumProp(Instance: TObject; Const PropInfo : PPropInfo; const Value: string);
  867. Var
  868. PV : Longint;
  869. begin
  870. If PropInfo<>Nil then
  871. begin
  872. PV:=GetEnumValue(PropInfo^.PropType, Value);
  873. if (PV<0) then
  874. raise EPropertyError.CreateFmt(SErrUnknownEnumValue, [Value]);
  875. SetOrdProp(Instance, PropInfo,PV);
  876. end;
  877. end;
  878. { ---------------------------------------------------------------------
  879. Int64 wrappers
  880. ---------------------------------------------------------------------}
  881. Function GetInt64Prop(Instance: TObject; PropInfo: PPropInfo): Int64;
  882. begin
  883. Result:=GetOrdProp(Instance,PropInfo);
  884. end;
  885. procedure SetInt64Prop(Instance: TObject; PropInfo: PPropInfo; const Value: Int64);
  886. begin
  887. SetOrdProp(Instance,PropInfo,Value);
  888. end;
  889. Function GetInt64Prop(Instance: TObject; const PropName: string): Int64;
  890. begin
  891. Result:=GetInt64Prop(Instance,FindPropInfo(Instance,PropName));
  892. end;
  893. Procedure SetInt64Prop(Instance: TObject; const PropName: string; const Value: Int64);
  894. begin
  895. SetInt64Prop(Instance,FindPropInfo(Instance,PropName),Value);
  896. end;
  897. { ---------------------------------------------------------------------
  898. Set properties
  899. ---------------------------------------------------------------------}
  900. Function GetSetProp(Instance: TObject; const PropName: string): string;
  901. begin
  902. Result:=GetSetProp(Instance,PropName,False);
  903. end;
  904. Function GetSetProp(Instance: TObject; const PropName: string; Brackets: Boolean): string;
  905. begin
  906. Result:=GetSetProp(Instance,FindPropInfo(Instance,PropName),Brackets);
  907. end;
  908. Function GetSetProp(Instance: TObject; const PropInfo: PPropInfo; Brackets: Boolean): string;
  909. begin
  910. Result:=SetToString(PropInfo,GetOrdProp(Instance,PropInfo),Brackets);
  911. end;
  912. Procedure SetSetProp(Instance: TObject; const PropName: string; const Value: string);
  913. begin
  914. SetSetProp(Instance,FindPropInfo(Instance,PropName),Value);
  915. end;
  916. Procedure SetSetProp(Instance: TObject; const PropInfo: PPropInfo; const Value: string);
  917. begin
  918. SetOrdProp(Instance,PropInfo,StringToSet(PropInfo,Value));
  919. end;
  920. { ---------------------------------------------------------------------
  921. Object properties
  922. ---------------------------------------------------------------------}
  923. Function GetObjectProp(Instance: TObject; const PropName: string): TObject;
  924. begin
  925. Result:=GetObjectProp(Instance,PropName,Nil);
  926. end;
  927. Function GetObjectProp(Instance: TObject; const PropName: string; MinClass: TClass): TObject;
  928. begin
  929. Result:=GetObjectProp(Instance,FindPropInfo(Instance,PropName),MinClass);
  930. end;
  931. Function GetObjectProp(Instance: TObject; PropInfo : PPropInfo): TObject;
  932. begin
  933. Result:=GetObjectProp(Instance,PropInfo,Nil);
  934. end;
  935. Function GetObjectProp(Instance: TObject; PropInfo : PPropInfo; MinClass: TClass): TObject;
  936. begin
  937. {$ifdef cpu64}
  938. Result:=TObject(GetInt64Prop(Instance,PropInfo));
  939. {$else cpu64}
  940. Result:=TObject(PtrInt(GetOrdProp(Instance,PropInfo)));
  941. {$endif cpu64}
  942. If (MinClass<>Nil) and (Result<>Nil) Then
  943. If Not Result.InheritsFrom(MinClass) then
  944. Result:=Nil;
  945. end;
  946. Procedure SetObjectProp(Instance: TObject; const PropName: string; Value: TObject);
  947. begin
  948. SetObjectProp(Instance,FindPropInfo(Instance,PropName),Value);
  949. end;
  950. Procedure SetObjectProp(Instance: TObject; PropInfo : PPropInfo; Value: TObject);
  951. begin
  952. {$ifdef cpu64}
  953. SetInt64Prop(Instance,PropInfo,Int64(Value));
  954. {$else cpu64}
  955. SetOrdProp(Instance,PropInfo,Integer(Value));
  956. {$endif cpu64}
  957. end;
  958. Function GetObjectPropClass(Instance: TObject; const PropName: string): TClass;
  959. begin
  960. Result:=GetTypeData(FindPropInfo(Instance,PropName)^.PropType)^.ClassType;
  961. end;
  962. { ---------------------------------------------------------------------
  963. Interface wrapprers
  964. ---------------------------------------------------------------------}
  965. function GetInterfaceProp(Instance: TObject; const PropName: string): IInterface;
  966. begin
  967. Result:=GetInterfaceProp(Instance,FindPropInfo(Instance,PropName));
  968. end;
  969. function GetInterfaceProp(Instance: TObject; PropInfo: PPropInfo): IInterface;
  970. begin
  971. {$ifdef cpu64}
  972. Result:=IInterface(GetInt64Prop(Instance,PropInfo));
  973. {$else cpu64}
  974. Result:=IInterface(PtrInt(GetOrdProp(Instance,PropInfo)));
  975. {$endif cpu64}
  976. end;
  977. procedure SetInterfaceProp(Instance: TObject; const PropName: string; const Value: IInterface);
  978. begin
  979. SetInterfaceProp(Instance,FindPropInfo(Instance,PropName),Value);
  980. end;
  981. procedure SetInterfaceProp(Instance: TObject; PropInfo: PPropInfo; const Value: IInterface);
  982. type
  983. TSetIntfStrProcIndex=procedure(index:longint;const i:IInterface) of object;
  984. TSetIntfStrProc=procedure(i:IInterface) of object;
  985. var
  986. AMethod : TMethod;
  987. begin
  988. case Propinfo^.PropType^.Kind of
  989. tkInterface:
  990. begin
  991. case (PropInfo^.PropProcs shr 2) and 3 of
  992. ptField:
  993. PInterface(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  994. ptstatic,
  995. ptvirtual :
  996. begin
  997. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  998. AMethod.Code:=PropInfo^.SetProc
  999. else
  1000. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1001. AMethod.Data:=Instance;
  1002. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1003. TSetIntfStrProcIndex(AMethod)(PropInfo^.Index,Value)
  1004. else
  1005. TSetIntfStrProc(AMethod)(Value);
  1006. end;
  1007. end;
  1008. end;
  1009. end;
  1010. end;
  1011. { ---------------------------------------------------------------------
  1012. String properties
  1013. ---------------------------------------------------------------------}
  1014. Function GetStrProp(Instance: TObject; PropInfo: PPropInfo): AnsiString;
  1015. type
  1016. TGetShortStrProcIndex=function(index:longint):ShortString of object;
  1017. TGetShortStrProc=function():ShortString of object;
  1018. TGetAnsiStrProcIndex=function(index:longint):AnsiString of object;
  1019. TGetAnsiStrProc=function():AnsiString of object;
  1020. var
  1021. AMethod : TMethod;
  1022. begin
  1023. Result:='';
  1024. case Propinfo^.PropType^.Kind of
  1025. tkWString:
  1026. Result:=GetWideStrProp(Instance,PropInfo);
  1027. tkSString:
  1028. begin
  1029. case (PropInfo^.PropProcs) and 3 of
  1030. ptField:
  1031. Result := PShortString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  1032. ptstatic,
  1033. ptvirtual :
  1034. begin
  1035. if (PropInfo^.PropProcs and 3)=ptStatic then
  1036. AMethod.Code:=PropInfo^.GetProc
  1037. else
  1038. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1039. AMethod.Data:=Instance;
  1040. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1041. Result:=TGetShortStrProcIndex(AMethod)(PropInfo^.Index)
  1042. else
  1043. Result:=TGetShortStrProc(AMethod)();
  1044. end;
  1045. end;
  1046. end;
  1047. tkAString:
  1048. begin
  1049. case (PropInfo^.PropProcs) and 3 of
  1050. ptField:
  1051. Result := PAnsiString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  1052. ptstatic,
  1053. ptvirtual :
  1054. begin
  1055. if (PropInfo^.PropProcs and 3)=ptStatic then
  1056. AMethod.Code:=PropInfo^.GetProc
  1057. else
  1058. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1059. AMethod.Data:=Instance;
  1060. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1061. Result:=TGetAnsiStrProcIndex(AMethod)(PropInfo^.Index)
  1062. else
  1063. Result:=TGetAnsiStrProc(AMethod)();
  1064. end;
  1065. end;
  1066. end;
  1067. end;
  1068. end;
  1069. Procedure SetStrProp(Instance : TObject;PropInfo : PPropInfo; const Value : AnsiString);
  1070. type
  1071. TSetShortStrProcIndex=procedure(index:longint;const s:ShortString) of object;
  1072. TSetShortStrProc=procedure(const s:ShortString) of object;
  1073. TSetAnsiStrProcIndex=procedure(index:longint;s:AnsiString) of object;
  1074. TSetAnsiStrProc=procedure(s:AnsiString) of object;
  1075. var
  1076. AMethod : TMethod;
  1077. begin
  1078. case Propinfo^.PropType^.Kind of
  1079. tkWString:
  1080. SetWideStrProp(Instance,PropInfo,Value);
  1081. tkSString:
  1082. begin
  1083. case (PropInfo^.PropProcs shr 2) and 3 of
  1084. ptField:
  1085. PShortString(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  1086. ptstatic,
  1087. ptvirtual :
  1088. begin
  1089. if (PropInfo^.PropProcs and 3)=ptStatic then
  1090. AMethod.Code:=PropInfo^.SetProc
  1091. else
  1092. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1093. AMethod.Data:=Instance;
  1094. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1095. TSetShortStrProcIndex(AMethod)(PropInfo^.Index,Value)
  1096. else
  1097. TSetShortStrProc(AMethod)(Value);
  1098. end;
  1099. end;
  1100. end;
  1101. tkAString:
  1102. begin
  1103. case (PropInfo^.PropProcs shr 2) and 3 of
  1104. ptField:
  1105. PAnsiString(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  1106. ptstatic,
  1107. ptvirtual :
  1108. begin
  1109. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1110. AMethod.Code:=PropInfo^.SetProc
  1111. else
  1112. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1113. AMethod.Data:=Instance;
  1114. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1115. TSetAnsiStrProcIndex(AMethod)(PropInfo^.Index,Value)
  1116. else
  1117. TSetAnsiStrProc(AMethod)(Value);
  1118. end;
  1119. end;
  1120. end;
  1121. end;
  1122. end;
  1123. Function GetStrProp(Instance: TObject; const PropName: string): string;
  1124. begin
  1125. Result:=GetStrProp(Instance,FindPropInfo(Instance,PropName));
  1126. end;
  1127. Procedure SetStrProp(Instance: TObject; const PropName: string; const Value: AnsiString);
  1128. begin
  1129. SetStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  1130. end;
  1131. Function GetWideStrProp(Instance: TObject; const PropName: string): WideString;
  1132. begin
  1133. Result:=GetWideStrProp(Instance, FindPropInfo(Instance, PropName));
  1134. end;
  1135. procedure SetWideStrProp(Instance: TObject; const PropName: string; const Value: WideString);
  1136. begin
  1137. SetWideStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  1138. end;
  1139. Function GetWideStrProp(Instance: TObject; PropInfo: PPropInfo): WideString;
  1140. type
  1141. TGetWideStrProcIndex=function(index:longint):WideString of object;
  1142. TGetWideStrProc=function():WideString of object;
  1143. var
  1144. AMethod : TMethod;
  1145. begin
  1146. Result:='';
  1147. case Propinfo^.PropType^.Kind of
  1148. tkSString,tkAString:
  1149. Result:=GetStrProp(Instance,PropInfo);
  1150. tkWString:
  1151. begin
  1152. case (PropInfo^.PropProcs) and 3 of
  1153. ptField:
  1154. Result := PWideString(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1155. ptstatic,
  1156. ptvirtual :
  1157. begin
  1158. if (PropInfo^.PropProcs and 3)=ptStatic then
  1159. AMethod.Code:=PropInfo^.GetProc
  1160. else
  1161. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1162. AMethod.Data:=Instance;
  1163. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1164. Result:=TGetWideStrProcIndex(AMethod)(PropInfo^.Index)
  1165. else
  1166. Result:=TGetWideStrProc(AMethod)();
  1167. end;
  1168. end;
  1169. end;
  1170. end;
  1171. end;
  1172. Procedure SetWideStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: WideString);
  1173. type
  1174. TSetWideStrProcIndex=procedure(index:longint;s:WideString) of object;
  1175. TSetWideStrProc=procedure(s:WideString) of object;
  1176. var
  1177. AMethod : TMethod;
  1178. begin
  1179. case Propinfo^.PropType^.Kind of
  1180. tkSString,tkAString:
  1181. SetStrProp(Instance,PropInfo,Value);
  1182. tkWString:
  1183. begin
  1184. case (PropInfo^.PropProcs shr 2) and 3 of
  1185. ptField:
  1186. PWideString(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1187. ptstatic,
  1188. ptvirtual :
  1189. begin
  1190. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1191. AMethod.Code:=PropInfo^.SetProc
  1192. else
  1193. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1194. AMethod.Data:=Instance;
  1195. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1196. TSetWideStrProcIndex(AMethod)(PropInfo^.Index,Value)
  1197. else
  1198. TSetWideStrProc(AMethod)(Value);
  1199. end;
  1200. end;
  1201. end;
  1202. end;
  1203. end;
  1204. Function GetUnicodeStrProp(Instance: TObject; const PropName: string): UnicodeString;
  1205. begin
  1206. Result:=GetUnicodeStrProp(Instance, FindPropInfo(Instance, PropName));
  1207. end;
  1208. procedure SetUnicodeStrProp(Instance: TObject; const PropName: string; const Value: UnicodeString);
  1209. begin
  1210. SetUnicodeStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  1211. end;
  1212. Function GetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo): UnicodeString;
  1213. type
  1214. TGetUnicodeStrProcIndex=function(index:longint):UnicodeString of object;
  1215. TGetUnicodeStrProc=function():UnicodeString of object;
  1216. var
  1217. AMethod : TMethod;
  1218. begin
  1219. Result:='';
  1220. case Propinfo^.PropType^.Kind of
  1221. tkSString,tkAString:
  1222. Result:=GetStrProp(Instance,PropInfo);
  1223. tkWString:
  1224. Result:=GetWideStrProp(Instance,PropInfo);
  1225. tkUString:
  1226. begin
  1227. case (PropInfo^.PropProcs) and 3 of
  1228. ptField:
  1229. Result := PUnicodeString(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1230. ptstatic,
  1231. ptvirtual :
  1232. begin
  1233. if (PropInfo^.PropProcs and 3)=ptStatic then
  1234. AMethod.Code:=PropInfo^.GetProc
  1235. else
  1236. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1237. AMethod.Data:=Instance;
  1238. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1239. Result:=TGetUnicodeStrProcIndex(AMethod)(PropInfo^.Index)
  1240. else
  1241. Result:=TGetUnicodeStrProc(AMethod)();
  1242. end;
  1243. end;
  1244. end;
  1245. end;
  1246. end;
  1247. Procedure SetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: UnicodeString);
  1248. type
  1249. TSetUnicodeStrProcIndex=procedure(index:longint;s:UnicodeString) of object;
  1250. TSetUnicodeStrProc=procedure(s:UnicodeString) of object;
  1251. var
  1252. AMethod : TMethod;
  1253. begin
  1254. case Propinfo^.PropType^.Kind of
  1255. tkSString,tkAString:
  1256. SetStrProp(Instance,PropInfo,Value);
  1257. tkWString:
  1258. SetWideStrProp(Instance,PropInfo,Value);
  1259. tkUString:
  1260. begin
  1261. case (PropInfo^.PropProcs shr 2) and 3 of
  1262. ptField:
  1263. PUnicodeString(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1264. ptstatic,
  1265. ptvirtual :
  1266. begin
  1267. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1268. AMethod.Code:=PropInfo^.SetProc
  1269. else
  1270. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1271. AMethod.Data:=Instance;
  1272. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1273. TSetUnicodeStrProcIndex(AMethod)(PropInfo^.Index,Value)
  1274. else
  1275. TSetUnicodeStrProc(AMethod)(Value);
  1276. end;
  1277. end;
  1278. end;
  1279. end;
  1280. end;
  1281. {$ifndef FPUNONE}
  1282. { ---------------------------------------------------------------------
  1283. Float properties
  1284. ---------------------------------------------------------------------}
  1285. function GetFloatProp(Instance : TObject;PropInfo : PPropInfo) : Extended;
  1286. type
  1287. TGetExtendedProc = function:Extended of object;
  1288. TGetExtendedProcIndex = function(Index: integer): Extended of object;
  1289. TGetDoubleProc = function:Double of object;
  1290. TGetDoubleProcIndex = function(Index: integer): Double of object;
  1291. TGetSingleProc = function:Single of object;
  1292. TGetSingleProcIndex = function(Index: integer):Single of object;
  1293. TGetCurrencyProc = function : Currency of object;
  1294. TGetCurrencyProcIndex = function(Index: integer) : Currency of object;
  1295. var
  1296. AMethod : TMethod;
  1297. begin
  1298. Result:=0.0;
  1299. case PropInfo^.PropProcs and 3 of
  1300. ptField:
  1301. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  1302. ftSingle:
  1303. Result:=PSingle(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1304. ftDouble:
  1305. Result:=PDouble(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1306. ftExtended:
  1307. Result:=PExtended(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1308. ftcomp:
  1309. Result:=PComp(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1310. ftcurr:
  1311. Result:=PCurrency(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1312. end;
  1313. ptStatic,
  1314. ptVirtual:
  1315. begin
  1316. if (PropInfo^.PropProcs and 3)=ptStatic then
  1317. AMethod.Code:=PropInfo^.GetProc
  1318. else
  1319. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1320. AMethod.Data:=Instance;
  1321. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  1322. ftSingle:
  1323. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  1324. Result:=TGetSingleProc(AMethod)()
  1325. else
  1326. Result:=TGetSingleProcIndex(AMethod)(PropInfo^.Index);
  1327. ftDouble:
  1328. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  1329. Result:=TGetDoubleProc(AMethod)()
  1330. else
  1331. Result:=TGetDoubleProcIndex(AMethod)(PropInfo^.Index);
  1332. ftExtended:
  1333. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  1334. Result:=TGetExtendedProc(AMethod)()
  1335. else
  1336. Result:=TGetExtendedProcIndex(AMethod)(PropInfo^.Index);
  1337. ftCurr:
  1338. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  1339. Result:=TGetCurrencyProc(AMethod)()
  1340. else
  1341. Result:=TGetCurrencyProcIndex(AMethod)(PropInfo^.Index);
  1342. end;
  1343. end;
  1344. end;
  1345. end;
  1346. Procedure SetFloatProp(Instance : TObject;PropInfo : PPropInfo; Value : Extended);
  1347. type
  1348. TSetExtendedProc = procedure(const AValue: Extended) of object;
  1349. TSetExtendedProcIndex = procedure(Index: integer; AValue: Extended) of object;
  1350. TSetDoubleProc = procedure(const AValue: Double) of object;
  1351. TSetDoubleProcIndex = procedure(Index: integer; AValue: Double) of object;
  1352. TSetSingleProc = procedure(const AValue: Single) of object;
  1353. TSetSingleProcIndex = procedure(Index: integer; AValue: Single) of object;
  1354. TSetCurrencyProc = procedure(const AValue: Currency) of object;
  1355. TSetCurrencyProcIndex = procedure(Index: integer; AValue: Currency) of object;
  1356. Var
  1357. AMethod : TMethod;
  1358. begin
  1359. case (PropInfo^.PropProcs shr 2) and 3 of
  1360. ptfield:
  1361. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  1362. ftSingle:
  1363. PSingle(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1364. ftDouble:
  1365. PDouble(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1366. ftExtended:
  1367. PExtended(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1368. {$ifdef FPC_COMP_IS_INT64}
  1369. ftComp:
  1370. PComp(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=trunc(Value);
  1371. {$else FPC_COMP_IS_INT64}
  1372. ftComp:
  1373. PComp(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Comp(Value);
  1374. {$endif FPC_COMP_IS_INT64}
  1375. ftCurr:
  1376. PCurrency(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1377. end;
  1378. ptStatic,
  1379. ptVirtual:
  1380. begin
  1381. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1382. AMethod.Code:=PropInfo^.SetProc
  1383. else
  1384. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1385. AMethod.Data:=Instance;
  1386. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  1387. ftSingle:
  1388. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  1389. TSetSingleProc(AMethod)(Value)
  1390. else
  1391. TSetSingleProcIndex(AMethod)(PropInfo^.Index,Value);
  1392. ftDouble:
  1393. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  1394. TSetDoubleProc(AMethod)(Value)
  1395. else
  1396. TSetDoubleProcIndex(AMethod)(PropInfo^.Index,Value);
  1397. ftExtended:
  1398. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  1399. TSetExtendedProc(AMethod)(Value)
  1400. else
  1401. TSetExtendedProcIndex(AMethod)(PropInfo^.Index,Value);
  1402. ftCurr:
  1403. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  1404. TSetCurrencyProc(AMethod)(Value)
  1405. else
  1406. TSetCurrencyProcIndex(AMethod)(PropInfo^.Index,Value);
  1407. end;
  1408. end;
  1409. end;
  1410. end;
  1411. function GetFloatProp(Instance: TObject; const PropName: string): Extended;
  1412. begin
  1413. Result:=GetFloatProp(Instance,FindPropInfo(Instance,PropName))
  1414. end;
  1415. Procedure SetFloatProp(Instance: TObject; const PropName: string; Value: Extended);
  1416. begin
  1417. SetFloatProp(Instance,FindPropInfo(Instance,PropName),Value);
  1418. end;
  1419. {$endif}
  1420. { ---------------------------------------------------------------------
  1421. Method properties
  1422. ---------------------------------------------------------------------}
  1423. Function GetMethodProp(Instance : TObject;PropInfo : PPropInfo) : TMethod;
  1424. type
  1425. TGetMethodProcIndex=function(Index: Longint): TMethod of object;
  1426. TGetMethodProc=function(): TMethod of object;
  1427. var
  1428. value: PMethod;
  1429. AMethod : TMethod;
  1430. begin
  1431. Result.Code:=nil;
  1432. Result.Data:=nil;
  1433. case (PropInfo^.PropProcs) and 3 of
  1434. ptfield:
  1435. begin
  1436. Value:=PMethod(Pointer(Instance)+PtrUInt(PropInfo^.GetProc));
  1437. if Value<>nil then
  1438. Result:=Value^;
  1439. end;
  1440. ptstatic,
  1441. ptvirtual :
  1442. begin
  1443. if (PropInfo^.PropProcs and 3)=ptStatic then
  1444. AMethod.Code:=PropInfo^.GetProc
  1445. else
  1446. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1447. AMethod.Data:=Instance;
  1448. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1449. Result:=TGetMethodProcIndex(AMethod)(PropInfo^.Index)
  1450. else
  1451. Result:=TGetMethodProc(AMethod)();
  1452. end;
  1453. end;
  1454. end;
  1455. Procedure SetMethodProp(Instance : TObject;PropInfo : PPropInfo; const Value : TMethod);
  1456. type
  1457. TSetMethodProcIndex=procedure(index:longint;p:TMethod) of object;
  1458. TSetMethodProc=procedure(p:TMethod) of object;
  1459. var
  1460. AMethod : TMethod;
  1461. begin
  1462. case (PropInfo^.PropProcs shr 2) and 3 of
  1463. ptfield:
  1464. PMethod(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^ := Value;
  1465. ptstatic,
  1466. ptvirtual :
  1467. begin
  1468. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1469. AMethod.Code:=PropInfo^.SetProc
  1470. else
  1471. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1472. AMethod.Data:=Instance;
  1473. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1474. TSetMethodProcIndex(AMethod)(PropInfo^.Index,Value)
  1475. else
  1476. TSetMethodProc(AMethod)(Value);
  1477. end;
  1478. end;
  1479. end;
  1480. Function GetMethodProp(Instance: TObject; const PropName: string): TMethod;
  1481. begin
  1482. Result:=GetMethodProp(Instance,FindPropInfo(Instance,PropName));
  1483. end;
  1484. Procedure SetMethodProp(Instance: TObject; const PropName: string; const Value: TMethod);
  1485. begin
  1486. SetMethodProp(Instance,FindPropInfo(Instance,PropName),Value);
  1487. end;
  1488. { ---------------------------------------------------------------------
  1489. Variant properties
  1490. ---------------------------------------------------------------------}
  1491. Procedure CheckVariantEvent(P : Pointer);
  1492. begin
  1493. If (P=Nil) then
  1494. Raise Exception.Create(SErrNoVariantSupport);
  1495. end;
  1496. Function GetVariantProp(Instance : TObject;PropInfo : PPropInfo): Variant;
  1497. begin
  1498. CheckVariantEvent(Pointer(OnGetVariantProp));
  1499. Result:=OnGetVariantProp(Instance,PropInfo);
  1500. end;
  1501. Procedure SetVariantProp(Instance : TObject;PropInfo : PPropInfo; const Value: Variant);
  1502. begin
  1503. CheckVariantEvent(Pointer(OnSetVariantProp));
  1504. OnSetVariantProp(Instance,PropInfo,Value);
  1505. end;
  1506. Function GetVariantProp(Instance: TObject; const PropName: string): Variant;
  1507. begin
  1508. Result:=GetVariantProp(Instance,FindPropInfo(Instance,PropName));
  1509. end;
  1510. Procedure SetVariantProp(Instance: TObject; const PropName: string; const Value: Variant);
  1511. begin
  1512. SetVariantprop(instance,FindpropInfo(Instance,PropName),Value);
  1513. end;
  1514. { ---------------------------------------------------------------------
  1515. All properties through variant.
  1516. ---------------------------------------------------------------------}
  1517. Function GetPropValue(Instance: TObject; const PropName: string): Variant;
  1518. begin
  1519. Result:=GetPropValue(Instance,PropName,True);
  1520. end;
  1521. Function GetPropValue(Instance: TObject; const PropName: string; PreferStrings: Boolean): Variant;
  1522. begin
  1523. CheckVariantEvent(Pointer(OnGetPropValue));
  1524. Result:=OnGetPropValue(Instance,PropName,PreferStrings)
  1525. end;
  1526. Procedure SetPropValue(Instance: TObject; const PropName: string; const Value: Variant);
  1527. begin
  1528. CheckVariantEvent(Pointer(OnSetPropValue));
  1529. OnSetPropValue(Instance,PropName,Value);
  1530. end;
  1531. { ---------------------------------------------------------------------
  1532. Easy access methods that appeared in Delphi 5
  1533. ---------------------------------------------------------------------}
  1534. Function IsPublishedProp(Instance: TObject; const PropName: string): Boolean;
  1535. begin
  1536. Result:=GetPropInfo(Instance,PropName)<>Nil;
  1537. end;
  1538. Function IsPublishedProp(AClass: TClass; const PropName: string): Boolean;
  1539. begin
  1540. Result:=GetPropInfo(AClass,PropName)<>Nil;
  1541. end;
  1542. Function PropIsType(Instance: TObject; const PropName: string; TypeKind: TTypeKind): Boolean;
  1543. begin
  1544. Result:=FindPropInfo(Instance,PropName)^.PropType^.Kind=TypeKind
  1545. end;
  1546. Function PropIsType(AClass: TClass; const PropName: string; TypeKind: TTypeKind): Boolean;
  1547. begin
  1548. Result:=PropType(AClass,PropName)=TypeKind
  1549. end;
  1550. Function PropType(Instance: TObject; const PropName: string): TTypeKind;
  1551. begin
  1552. Result:=FindPropInfo(Instance,PropName)^.PropType^.Kind;
  1553. end;
  1554. Function PropType(AClass: TClass; const PropName: string): TTypeKind;
  1555. begin
  1556. Result:=FindPropInfo(AClass,PropName)^.PropType^.Kind;
  1557. end;
  1558. Function IsStoredProp(Instance: TObject; const PropName: string): Boolean;
  1559. begin
  1560. Result:=IsStoredProp(instance,FindPropInfo(Instance,PropName));
  1561. end;
  1562. end.