typinfo.pp 58 KB

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