typinfo.pp 58 KB

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