typinfo.pp 78 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533
  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. {$MODESWITCH AdvancedRecords}
  17. {$inline on}
  18. {$macro on}
  19. {$h+}
  20. uses SysUtils;
  21. // temporary types:
  22. type
  23. {$MINENUMSIZE 1 this saves a lot of memory }
  24. {$ifdef FPC_RTTI_PACKSET1}
  25. { for Delphi compatibility }
  26. {$packset 1}
  27. {$endif}
  28. // if you change one of the following enumeration types
  29. // you have also to change the compiler in an appropriate way !
  30. TTypeKind = (tkUnknown,tkInteger,tkChar,tkEnumeration,tkFloat,
  31. tkSet,tkMethod,tkSString,tkLString,tkAString,
  32. tkWString,tkVariant,tkArray,tkRecord,tkInterface,
  33. tkClass,tkObject,tkWChar,tkBool,tkInt64,tkQWord,
  34. tkDynArray,tkInterfaceRaw,tkProcVar,tkUString,tkUChar,
  35. tkHelper,tkFile,tkClassRef,tkPointer);
  36. TOrdType = (otSByte,otUByte,otSWord,otUWord,otSLong,otULong,otSQWord,otUQWord);
  37. {$ifndef FPUNONE}
  38. TFloatType = (ftSingle,ftDouble,ftExtended,ftComp,ftCurr);
  39. {$endif}
  40. TMethodKind = (mkProcedure,mkFunction,mkConstructor,mkDestructor,
  41. mkClassProcedure,mkClassFunction,mkClassConstructor,
  42. mkClassDestructor,mkOperatorOverload);
  43. TParamFlag = (pfVar,pfConst,pfArray,pfAddress,pfReference,pfOut,pfConstRef
  44. {$ifndef VER3_0},pfHidden,pfHigh,pfSelf,pfVmt{$endif VER3_0}
  45. );
  46. TParamFlags = set of TParamFlag;
  47. TIntfFlag = (ifHasGuid,ifDispInterface,ifDispatch,ifHasStrGUID);
  48. TIntfFlags = set of TIntfFlag;
  49. TIntfFlagsBase = set of TIntfFlag;
  50. // don't rely on integer values of TCallConv since it includes all conventions
  51. // which both delphi and fpc support. In the future delphi can support more and
  52. // fpc own conventions will be shifted/reordered accordinly
  53. TCallConv = (ccReg, ccCdecl, ccPascal, ccStdCall, ccSafeCall,
  54. ccCppdecl, ccFar16, ccOldFPCCall, ccInternProc,
  55. ccSysCall, ccSoftFloat, ccMWPascal);
  56. {$push}
  57. {$scopedenums on}
  58. TSubRegister = (
  59. None,
  60. Lo,
  61. Hi,
  62. Word,
  63. DWord,
  64. QWord,
  65. FloatSingle,
  66. FloatDouble,
  67. FloatQuad,
  68. MultiMediaSingle,
  69. MultiMediaDouble,
  70. MultiMediaWhole,
  71. MultiMediaX,
  72. MultiMediaY
  73. );
  74. TRegisterType = (
  75. Invalid,
  76. Int,
  77. FP,
  78. MMX,
  79. MultiMedia,
  80. Special,
  81. Address
  82. );
  83. {$pop}
  84. {$MINENUMSIZE DEFAULT}
  85. const
  86. ptField = 0;
  87. ptStatic = 1;
  88. ptVirtual = 2;
  89. ptConst = 3;
  90. type
  91. TTypeKinds = set of TTypeKind;
  92. ShortStringBase = string[255];
  93. TParameterLocation =
  94. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  95. packed
  96. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  97. record
  98. private
  99. LocType: Byte;
  100. function GetRegType: TRegisterType; inline;
  101. function GetReference: Boolean; inline;
  102. function GetShiftVal: Int8; inline;
  103. public
  104. RegSub: TSubRegister;
  105. RegNumber: Word;
  106. { Stack offset if Reference, ShiftVal if not }
  107. Offset: SizeInt;
  108. { if Reference then the register is the index register otherwise the
  109. register in wihch (part of) the parameter resides }
  110. property Reference: Boolean read GetReference;
  111. property RegType: TRegisterType read GetRegType;
  112. { if Reference, otherwise 0 }
  113. property ShiftVal: Int8 read GetShiftVal;
  114. end;
  115. PParameterLocation = ^TParameterLocation;
  116. PParameterLocations = ^TParameterLocations;
  117. TParameterLocations =
  118. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  119. packed
  120. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  121. record
  122. private
  123. function GetLocation(aIndex: Byte): PParameterLocation; inline;
  124. public
  125. Count: Byte;
  126. property Location[Index: Byte]: PParameterLocation read GetLocation;
  127. end;
  128. PVmtFieldEntry = ^TVmtFieldEntry;
  129. TVmtFieldEntry =
  130. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  131. packed
  132. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  133. record
  134. FieldOffset: PtrUInt;
  135. TypeIndex: Word;
  136. Name: ShortString;
  137. end;
  138. PVmtFieldTable = ^TVmtFieldTable;
  139. TVmtFieldTable =
  140. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  141. packed
  142. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  143. record
  144. Count: Word;
  145. ClassTab: Pointer;
  146. { should be array[Word] of TFieldInfo; but
  147. Elements have variant size! force at least proper alignment }
  148. Fields: array[0..0] of TVmtFieldEntry
  149. end;
  150. {$PACKRECORDS 1}
  151. TTypeInfo = record
  152. Kind : TTypeKind;
  153. Name : ShortString;
  154. // here the type data follows as TTypeData record
  155. end;
  156. PTypeInfo = ^TTypeInfo;
  157. PPTypeInfo = ^PTypeInfo;
  158. { Note: these are only for backwards compatibility. New type references should
  159. only use PPTypeInfo directly! }
  160. {$ifdef ver3_0}
  161. {$define TypeInfoPtr := PTypeInfo}
  162. {$else}
  163. {$define TypeInfoPtr := PPTypeInfo}
  164. {$endif}
  165. {$PACKRECORDS C}
  166. // members of TTypeData
  167. TArrayTypeData =
  168. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  169. packed
  170. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  171. record
  172. private
  173. function GetElType: PTypeInfo; inline;
  174. function GetDims(aIndex: Byte): PTypeInfo; inline;
  175. public
  176. property ElType: PTypeInfo read GetElType;
  177. property Dims[Index: Byte]: PTypeInfo read GetDims;
  178. public
  179. Size: SizeInt;
  180. ElCount: SizeInt;
  181. ElTypeRef: TypeInfoPtr;
  182. DimCount: Byte;
  183. DimsRef: array[0..255] of TypeInfoPtr;
  184. end;
  185. PManagedField = ^TManagedField;
  186. TManagedField =
  187. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  188. packed
  189. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  190. record
  191. private
  192. function GetTypeRef: PTypeInfo; inline;
  193. public
  194. property TypeRef: PTypeInfo read GetTypeRef;
  195. public
  196. TypeRefRef: TypeInfoPtr;
  197. FldOffset: SizeInt;
  198. end;
  199. PInitManagedField = ^TInitManagedField;
  200. TInitManagedField = TManagedField;
  201. PProcedureParam = ^TProcedureParam;
  202. TProcedureParam =
  203. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  204. packed
  205. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  206. record
  207. private
  208. function GetParamType: PTypeInfo; inline;
  209. function GetFlags: Byte; inline;
  210. public
  211. property ParamType: PTypeInfo read GetParamType;
  212. property Flags: Byte read GetFlags;
  213. public
  214. ParamFlags: TParamFlags;
  215. ParamTypeRef: TypeInfoPtr;
  216. Name: ShortString;
  217. end;
  218. TProcedureSignature =
  219. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  220. packed
  221. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  222. record
  223. private
  224. function GetResultType: PTypeInfo; inline;
  225. public
  226. property ResultType: PTypeInfo read GetResultType;
  227. public
  228. Flags: Byte;
  229. CC: TCallConv;
  230. ResultTypeRef: TypeInfoPtr;
  231. ParamCount: Byte;
  232. {Params: array[0..ParamCount - 1] of TProcedureParam;}
  233. function GetParam(ParamIndex: Integer): PProcedureParam;
  234. end;
  235. PRecInitData = ^TRecInitData;
  236. TRecInitData =
  237. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  238. packed
  239. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  240. record
  241. Terminator: Pointer;
  242. Size: Integer;
  243. ManagedFieldCount: Integer;
  244. { ManagedFields: array[0..ManagedFieldCount - 1] of TInitManagedField ; }
  245. end;
  246. PTypeData = ^TTypeData;
  247. TTypeData =
  248. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  249. packed
  250. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  251. record
  252. private
  253. function GetBaseType: PTypeInfo; inline;
  254. function GetCompType: PTypeInfo; inline;
  255. function GetParentInfo: PTypeInfo; inline;
  256. {$ifndef VER3_0}
  257. function GetRecInitData: PRecInitData; inline;
  258. {$endif}
  259. function GetHelperParent: PTypeInfo; inline;
  260. function GetExtendedInfo: PTypeInfo; inline;
  261. function GetIntfParent: PTypeInfo; inline;
  262. function GetRawIntfParent: PTypeInfo; inline;
  263. function GetIIDStr: ShortString; inline;
  264. function GetElType: PTypeInfo; inline;
  265. function GetElType2: PTypeInfo; inline;
  266. function GetInstanceType: PTypeInfo; inline;
  267. function GetRefType: PTypeInfo; inline;
  268. public
  269. { tkEnumeration }
  270. property BaseType: PTypeInfo read GetBaseType;
  271. { tkSet }
  272. property CompType: PTypeInfo read GetCompType;
  273. { tkClass }
  274. property ParentInfo: PTypeInfo read GetParentInfo;
  275. { tkRecord }
  276. {$ifndef VER3_0}
  277. property RecInitData: PRecInitData read GetRecInitData;
  278. {$endif}
  279. { tkHelper }
  280. property HelperParent: PTypeInfo read GetHelperParent;
  281. property ExtendedInfo: PTypeInfo read GetExtendedInfo;
  282. { tkInterface }
  283. property IntfParent: PTypeInfo read GetIntfParent;
  284. { tkInterfaceRaw }
  285. property RawIntfParent: PTypeInfo read GetRawIntfParent;
  286. property IIDStr: ShortString read GetIIDStr;
  287. { tkDynArray }
  288. property ElType2: PTypeInfo read GetElType2;
  289. property ElType: PTypeInfo read GetElType;
  290. { tkClassRef }
  291. property InstanceType: PTypeInfo read GetInstanceType;
  292. { tkPointer }
  293. property RefType: PTypeInfo read GetRefType;
  294. public
  295. case TTypeKind of
  296. tkUnKnown,tkLString,tkWString,tkVariant,tkUString:
  297. ();
  298. tkAString:
  299. (CodePage: Word);
  300. {$ifndef VER3_0}
  301. tkInt64,tkQWord,
  302. {$endif VER3_0}
  303. tkInteger,tkChar,tkEnumeration,tkBool,tkWChar,tkSet:
  304. (OrdType : TOrdType;
  305. case TTypeKind of
  306. tkInteger,tkChar,tkEnumeration,tkBool,tkWChar : (
  307. MinValue,MaxValue : Longint;
  308. case TTypeKind of
  309. tkEnumeration:
  310. (
  311. BaseTypeRef : TypeInfoPtr;
  312. NameList : ShortString;
  313. {EnumUnitName: ShortString;})
  314. );
  315. {$ifndef VER3_0}
  316. {tkBool with OrdType=otSQWord }
  317. tkInt64:
  318. (MinInt64Value, MaxInt64Value: Int64);
  319. {tkBool with OrdType=otUQWord }
  320. tkQWord:
  321. (MinQWordValue, MaxQWordValue: QWord);
  322. {$endif VER3_0}
  323. tkSet:
  324. (CompTypeRef : TypeInfoPtr)
  325. );
  326. {$ifndef FPUNONE}
  327. tkFloat:
  328. (FloatType : TFloatType);
  329. {$endif}
  330. tkSString:
  331. (MaxLength : Byte);
  332. tkClass:
  333. (ClassType : TClass;
  334. ParentInfoRef : TypeInfoPtr;
  335. PropCount : SmallInt;
  336. UnitName : ShortString
  337. // here the properties follow as array of TPropInfo
  338. );
  339. tkRecord:
  340. (
  341. {$ifndef VER3_0}
  342. RecInitInfo: Pointer; { points to TTypeInfo followed by init table }
  343. {$endif VER3_0}
  344. RecSize: Integer;
  345. case Boolean of
  346. False: (ManagedFldCount: Integer deprecated 'Use RecInitData^.ManagedFieldCount or TotalFieldCount depending on your use case');
  347. True: (TotalFieldCount: Integer);
  348. {ManagedFields: array[1..TotalFieldCount] of TManagedField}
  349. );
  350. tkHelper:
  351. (HelperParentRef : TypeInfoPtr;
  352. ExtendedInfoRef : TypeInfoPtr;
  353. HelperProps : SmallInt;
  354. HelperUnit : ShortString
  355. // here the properties follow as array of TPropInfo
  356. );
  357. tkMethod:
  358. (MethodKind : TMethodKind;
  359. ParamCount : Byte;
  360. ParamList : array[0..1023] of Char
  361. {in reality ParamList is a array[1..ParamCount] of:
  362. record
  363. Flags : TParamFlags;
  364. ParamName : ShortString;
  365. TypeName : ShortString;
  366. end;
  367. followed by
  368. ResultType : ShortString // for mkFunction, mkClassFunction only
  369. ResultTypeRef : PPTypeInfo; // for mkFunction, mkClassFunction only
  370. CC : TCallConv;
  371. ParamTypeRefs : array[1..ParamCount] of PPTypeInfo;}
  372. );
  373. tkProcVar:
  374. (ProcSig: TProcedureSignature);
  375. {$ifdef VER3_0}
  376. tkInt64:
  377. (MinInt64Value, MaxInt64Value: Int64);
  378. tkQWord:
  379. (MinQWordValue, MaxQWordValue: QWord);
  380. {$endif VER3_0}
  381. tkInterface:
  382. (
  383. IntfParentRef: TypeInfoPtr;
  384. IntfFlags : TIntfFlagsBase;
  385. GUID: TGUID;
  386. IntfUnit: ShortString;
  387. { here the properties follow as Word Count & array of TPropInfo }
  388. );
  389. tkInterfaceRaw:
  390. (
  391. RawIntfParentRef: TypeInfoPtr;
  392. RawIntfFlags : TIntfFlagsBase;
  393. IID: TGUID;
  394. RawIntfUnit: ShortString;
  395. { IIDStr: ShortString; }
  396. { here the properties follow as Word Count & array of TPropInfo }
  397. );
  398. tkArray:
  399. (ArrayData: TArrayTypeData);
  400. tkDynArray:
  401. (
  402. elSize : PtrUInt;
  403. elType2Ref : TypeInfoPtr;
  404. varType : Longint;
  405. elTypeRef : TypeInfoPtr;
  406. DynUnitName: ShortStringBase
  407. );
  408. tkClassRef:
  409. (InstanceTypeRef: TypeInfoPtr);
  410. tkPointer:
  411. (RefTypeRef: TypeInfoPtr);
  412. end;
  413. PPropData = ^TPropData;
  414. TPropData =
  415. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  416. packed
  417. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  418. record
  419. PropCount : Word;
  420. PropList : record _alignmentdummy : ptrint; end;
  421. end;
  422. {$PACKRECORDS 1}
  423. PPropInfo = ^TPropInfo;
  424. TPropInfo = packed record
  425. private
  426. function GetPropType: PTypeInfo; inline;
  427. public
  428. PropTypeRef : TypeInfoPtr;
  429. GetProc : CodePointer;
  430. SetProc : CodePointer;
  431. StoredProc : CodePointer;
  432. Index : Integer;
  433. Default : Longint;
  434. NameIndex : SmallInt;
  435. // contains the type of the Get/Set/Storedproc, see also ptxxx
  436. // bit 0..1 GetProc
  437. // 2..3 SetProc
  438. // 4..5 StoredProc
  439. // 6 : true, constant index property
  440. PropProcs : Byte;
  441. Name : ShortString;
  442. property PropType: PTypeInfo read GetPropType;
  443. end;
  444. TProcInfoProc = Procedure(PropInfo : PPropInfo) of object;
  445. PPropList = ^TPropList;
  446. TPropList = array[0..{$ifdef cpu16}(32768 div sizeof(PPropInfo))-2{$else}65535{$endif}] of PPropInfo;
  447. const
  448. tkString = tkSString;
  449. tkProcedure = tkProcVar; // for compatibility with Delphi
  450. tkAny = [Low(TTypeKind)..High(TTypeKind)];
  451. tkMethods = [tkMethod];
  452. tkProperties = tkAny-tkMethods-[tkUnknown];
  453. // general property handling
  454. Function GetTypeData(TypeInfo : PTypeInfo) : PTypeData;
  455. Function AlignTypeData(p : PTypeData) : PTypeData;
  456. Function GetPropInfo(TypeInfo: PTypeInfo;const PropName: string): PPropInfo;
  457. Function GetPropInfo(TypeInfo: PTypeInfo;const PropName: string; AKinds: TTypeKinds): PPropInfo;
  458. Function GetPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  459. Function GetPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  460. Function GetPropInfo(AClass: TClass; const PropName: string): PPropInfo;
  461. Function GetPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  462. Function FindPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  463. Function FindPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  464. Function FindPropInfo(AClass: TClass; const PropName: string): PPropInfo;
  465. Function FindPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  466. Procedure GetPropInfos(TypeInfo: PTypeInfo; PropList: PPropList);
  467. Function GetPropList(TypeInfo: PTypeInfo; TypeKinds: TTypeKinds; PropList: PPropList; Sorted: boolean = true): longint;
  468. Function GetPropList(TypeInfo: PTypeInfo; out PropList: PPropList): SizeInt;
  469. function GetPropList(AClass: TClass; out PropList: PPropList): Integer;
  470. function GetPropList(Instance: TObject; out PropList: PPropList): Integer;
  471. // Property information routines.
  472. Function IsStoredProp(Instance: TObject;PropInfo : PPropInfo) : Boolean;
  473. Function IsStoredProp(Instance: TObject; const PropName: string): Boolean;
  474. Function IsPublishedProp(Instance: TObject; const PropName: string): Boolean;
  475. Function IsPublishedProp(AClass: TClass; const PropName: string): Boolean;
  476. Function PropType(Instance: TObject; const PropName: string): TTypeKind;
  477. Function PropType(AClass: TClass; const PropName: string): TTypeKind;
  478. Function PropIsType(Instance: TObject; const PropName: string; TypeKind: TTypeKind): Boolean;
  479. Function PropIsType(AClass: TClass; const PropName: string; TypeKind: TTypeKind): Boolean;
  480. // subroutines to read/write properties
  481. Function GetOrdProp(Instance: TObject; PropInfo : PPropInfo) : Int64;
  482. Function GetOrdProp(Instance: TObject; const PropName: string): Int64;
  483. Procedure SetOrdProp(Instance: TObject; PropInfo : PPropInfo; Value : Int64);
  484. Procedure SetOrdProp(Instance: TObject; const PropName: string; Value: Int64);
  485. Function GetEnumProp(Instance: TObject; const PropName: string): string;
  486. Function GetEnumProp(Instance: TObject; const PropInfo: PPropInfo): string;
  487. Procedure SetEnumProp(Instance: TObject; const PropName: string;const Value: string);
  488. Procedure SetEnumProp(Instance: TObject; const PropInfo: PPropInfo;const Value: string);
  489. Function GetSetProp(Instance: TObject; const PropName: string): string;
  490. Function GetSetProp(Instance: TObject; const PropName: string; Brackets: Boolean): string;
  491. Function GetSetProp(Instance: TObject; const PropInfo: PPropInfo; Brackets: Boolean): string;
  492. Procedure SetSetProp(Instance: TObject; const PropName: string; const Value: string);
  493. Procedure SetSetProp(Instance: TObject; const PropInfo: PPropInfo; const Value: string);
  494. Function GetStrProp(Instance: TObject; PropInfo : PPropInfo) : Ansistring;
  495. Function GetStrProp(Instance: TObject; const PropName: string): string;
  496. Procedure SetStrProp(Instance: TObject; const PropName: string; const Value: AnsiString);
  497. Procedure SetStrProp(Instance: TObject; PropInfo : PPropInfo; const Value : Ansistring);
  498. Function GetWideStrProp(Instance: TObject; PropInfo: PPropInfo): WideString;
  499. Function GetWideStrProp(Instance: TObject; const PropName: string): WideString;
  500. Procedure SetWideStrProp(Instance: TObject; const PropName: string; const Value: WideString);
  501. Procedure SetWideStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: WideString);
  502. Function GetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo): UnicodeString;
  503. Function GetUnicodeStrProp(Instance: TObject; const PropName: string): UnicodeString;
  504. Procedure SetUnicodeStrProp(Instance: TObject; const PropName: string; const Value: UnicodeString);
  505. Procedure SetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: UnicodeString);
  506. {$ifndef FPUNONE}
  507. Function GetFloatProp(Instance: TObject; PropInfo : PPropInfo) : Extended;
  508. Function GetFloatProp(Instance: TObject; const PropName: string): Extended;
  509. Procedure SetFloatProp(Instance: TObject; const PropName: string; Value: Extended);
  510. Procedure SetFloatProp(Instance: TObject; PropInfo : PPropInfo; Value : Extended);
  511. {$endif}
  512. Function GetObjectProp(Instance: TObject; const PropName: string): TObject;
  513. Function GetObjectProp(Instance: TObject; const PropName: string; MinClass: TClass): TObject;
  514. Function GetObjectProp(Instance: TObject; PropInfo: PPropInfo): TObject;
  515. Function GetObjectProp(Instance: TObject; PropInfo: PPropInfo; MinClass: TClass): TObject;
  516. Procedure SetObjectProp(Instance: TObject; const PropName: string; Value: TObject);
  517. Procedure SetObjectProp(Instance: TObject; PropInfo: PPropInfo; Value: TObject);
  518. Function GetObjectPropClass(Instance: TObject; const PropName: string): TClass;
  519. Function GetObjectPropClass(AClass: TClass; const PropName: string): TClass;
  520. Function GetMethodProp(Instance: TObject; PropInfo: PPropInfo) : TMethod;
  521. Function GetMethodProp(Instance: TObject; const PropName: string): TMethod;
  522. Procedure SetMethodProp(Instance: TObject; PropInfo: PPropInfo; const Value : TMethod);
  523. Procedure SetMethodProp(Instance: TObject; const PropName: string; const Value: TMethod);
  524. Function GetInt64Prop(Instance: TObject; PropInfo: PPropInfo): Int64;
  525. Function GetInt64Prop(Instance: TObject; const PropName: string): Int64;
  526. Procedure SetInt64Prop(Instance: TObject; PropInfo: PPropInfo; const Value: Int64);
  527. Procedure SetInt64Prop(Instance: TObject; const PropName: string; const Value: Int64);
  528. Function GetPropValue(Instance: TObject; const PropName: string): Variant;
  529. Function GetPropValue(Instance: TObject; const PropName: string; PreferStrings: Boolean): Variant;
  530. Function GetPropValue(Instance: TObject; PropInfo: PPropInfo): Variant;
  531. Function GetPropValue(Instance: TObject; PropInfo: PPropInfo; PreferStrings: Boolean): Variant;
  532. Procedure SetPropValue(Instance: TObject; const PropName: string; const Value: Variant);
  533. Procedure SetPropValue(Instance: TObject; PropInfo: PPropInfo; const Value: Variant);
  534. Function GetVariantProp(Instance: TObject; PropInfo : PPropInfo): Variant;
  535. Function GetVariantProp(Instance: TObject; const PropName: string): Variant;
  536. Procedure SetVariantProp(Instance: TObject; const PropName: string; const Value: Variant);
  537. Procedure SetVariantProp(Instance: TObject; PropInfo : PPropInfo; const Value: Variant);
  538. function GetInterfaceProp(Instance: TObject; const PropName: string): IInterface;
  539. function GetInterfaceProp(Instance: TObject; PropInfo: PPropInfo): IInterface;
  540. procedure SetInterfaceProp(Instance: TObject; const PropName: string; const Value: IInterface);
  541. procedure SetInterfaceProp(Instance: TObject; PropInfo: PPropInfo; const Value: IInterface);
  542. function GetRawInterfaceProp(Instance: TObject; const PropName: string): Pointer;
  543. function GetRawInterfaceProp(Instance: TObject; PropInfo: PPropInfo): Pointer;
  544. procedure SetRawInterfaceProp(Instance: TObject; const PropName: string; const Value: Pointer);
  545. procedure SetRawInterfaceProp(Instance: TObject; PropInfo: PPropInfo; const Value: Pointer);
  546. function GetDynArrayProp(Instance: TObject; const PropName: string): Pointer;
  547. function GetDynArrayProp(Instance: TObject; PropInfo: PPropInfo): Pointer;
  548. procedure SetDynArrayProp(Instance: TObject; const PropName: string; const Value: Pointer);
  549. procedure SetDynArrayProp(Instance: TObject; PropInfo: PPropInfo; const Value: Pointer);
  550. // Auxiliary routines, which may be useful
  551. Function GetEnumName(TypeInfo : PTypeInfo;Value : Integer) : string;
  552. Function GetEnumValue(TypeInfo : PTypeInfo;const Name : string) : Integer;
  553. function GetEnumNameCount(enum1: PTypeInfo): SizeInt;
  554. function SetToString(TypeInfo: PTypeInfo; Value: Integer; Brackets: Boolean) : String;
  555. function SetToString(PropInfo: PPropInfo; Value: Integer; Brackets: Boolean) : String;
  556. function SetToString(PropInfo: PPropInfo; Value: Integer) : String;
  557. function StringToSet(PropInfo: PPropInfo; const Value: string): Integer;
  558. function StringToSet(TypeInfo: PTypeInfo; const Value: string): Integer;
  559. const
  560. BooleanIdents: array[Boolean] of String = ('False', 'True');
  561. DotSep: String = '.';
  562. Type
  563. EPropertyError = Class(Exception);
  564. TGetPropValue = Function (Instance: TObject; PropInfo: PPropInfo; PreferStrings: Boolean) : Variant;
  565. TSetPropValue = Procedure (Instance: TObject; PropInfo: PPropInfo; const Value: Variant);
  566. TGetVariantProp = Function (Instance: TObject; PropInfo : PPropInfo): Variant;
  567. TSetVariantProp = Procedure (Instance: TObject; PropInfo : PPropInfo; const Value: Variant);
  568. EPropertyConvertError = class(Exception); // Not used (yet), but defined for compatibility.
  569. Const
  570. OnGetPropValue : TGetPropValue = Nil;
  571. OnSetPropValue : TSetPropValue = Nil;
  572. OnGetVariantprop : TGetVariantProp = Nil;
  573. OnSetVariantprop : TSetVariantProp = Nil;
  574. { for inlining }
  575. function DerefTypeInfoPtr(Info: TypeInfoPtr): PTypeInfo; inline;
  576. Implementation
  577. uses rtlconsts;
  578. type
  579. PMethod = ^TMethod;
  580. { ---------------------------------------------------------------------
  581. Auxiliary methods
  582. ---------------------------------------------------------------------}
  583. function aligntoptr(p : pointer) : pointer;inline;
  584. begin
  585. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  586. result:=align(p,sizeof(p));
  587. {$else FPC_REQUIRES_PROPER_ALIGNMENT}
  588. result:=p;
  589. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  590. end;
  591. function DerefTypeInfoPtr(Info: TypeInfoPtr): PTypeInfo; inline;
  592. begin
  593. {$ifdef ver3_0}
  594. Result := Info;
  595. {$else}
  596. if not Assigned(Info) then
  597. Result := Nil
  598. else
  599. Result := Info^;
  600. {$endif}
  601. end;
  602. Function GetEnumName(TypeInfo : PTypeInfo;Value : Integer) : string;
  603. Var PS : PShortString;
  604. PT : PTypeData;
  605. begin
  606. PT:=GetTypeData(TypeInfo);
  607. if TypeInfo^.Kind=tkBool then
  608. begin
  609. case Value of
  610. 0,1:
  611. Result:=BooleanIdents[Boolean(Value)];
  612. else
  613. Result:='';
  614. end;
  615. end
  616. else
  617. begin
  618. PS:=@PT^.NameList;
  619. dec(Value,PT^.MinValue);
  620. While Value>0 Do
  621. begin
  622. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  623. Dec(Value);
  624. end;
  625. Result:=PS^;
  626. end;
  627. end;
  628. Function GetEnumValue(TypeInfo : PTypeInfo;const Name : string) : Integer;
  629. Var PS : PShortString;
  630. PT : PTypeData;
  631. Count : longint;
  632. sName: shortstring;
  633. begin
  634. If Length(Name)=0 then
  635. exit(-1);
  636. sName := Name;
  637. PT:=GetTypeData(TypeInfo);
  638. Count:=0;
  639. Result:=-1;
  640. if TypeInfo^.Kind=tkBool then
  641. begin
  642. If CompareText(BooleanIdents[false],Name)=0 then
  643. result:=0
  644. else if CompareText(BooleanIdents[true],Name)=0 then
  645. result:=1;
  646. end
  647. else
  648. begin
  649. PS:=@PT^.NameList;
  650. While (Result=-1) and (PByte(PS)^<>0) do
  651. begin
  652. If ShortCompareText(PS^, sName) = 0 then
  653. Result:=Count+PT^.MinValue;
  654. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  655. Inc(Count);
  656. end;
  657. end;
  658. end;
  659. function GetEnumNameCount(enum1: PTypeInfo): SizeInt;
  660. var
  661. PS: PShortString;
  662. PT: PTypeData;
  663. Count: SizeInt;
  664. begin
  665. PT:=GetTypeData(enum1);
  666. if enum1^.Kind=tkBool then
  667. Result:=2
  668. else
  669. begin
  670. Count:=0;
  671. Result:=0;
  672. PS:=@PT^.NameList;
  673. While (PByte(PS)^<>0) do
  674. begin
  675. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  676. Inc(Count);
  677. end;
  678. { the last string is the unit name }
  679. Result := Count - 1;
  680. end;
  681. end;
  682. Function SetToString(PropInfo: PPropInfo; Value: Integer; Brackets: Boolean) : String;
  683. begin
  684. Result:=SetToString(PropInfo^.PropType,Value,Brackets);
  685. end;
  686. Function SetToString(TypeInfo: PTypeInfo; Value: Integer; Brackets: Boolean) : String;
  687. type
  688. tsetarr = bitpacked array[0..SizeOf(Integer)*8-1] of 0..1;
  689. Var
  690. I : Integer;
  691. PTI : PTypeInfo;
  692. begin
  693. {$if defined(FPC_BIG_ENDIAN)}
  694. { On big endian systems, set element 0 is in the most significant bit,
  695. and the same goes for the elements of bitpacked arrays there. }
  696. case GetTypeData(TypeInfo)^.OrdType of
  697. otSByte,otUByte: Value:=Value shl (SizeOf(Integer)*8-8);
  698. otSWord,otUWord: Value:=Value shl (SizeOf(Integer)*8-16);
  699. end;
  700. {$endif}
  701. PTI:=GetTypeData(TypeInfo)^.CompType;
  702. Result:='';
  703. For I:=0 to SizeOf(Integer)*8-1 do
  704. begin
  705. if (tsetarr(Value)[i]<>0) then
  706. begin
  707. If Result='' then
  708. Result:=GetEnumName(PTI,i)
  709. else
  710. Result:=Result+','+GetEnumName(PTI,I);
  711. end;
  712. end;
  713. if Brackets then
  714. Result:='['+Result+']';
  715. end;
  716. Function SetToString(PropInfo: PPropInfo; Value: Integer) : String;
  717. begin
  718. Result:=SetToString(PropInfo,Value,False);
  719. end;
  720. Const
  721. SetDelim = ['[',']',',',' '];
  722. Function GetNextElement(Var S : String) : String;
  723. Var
  724. J : Integer;
  725. begin
  726. J:=1;
  727. Result:='';
  728. If Length(S)>0 then
  729. begin
  730. While (J<=Length(S)) and Not (S[j] in SetDelim) do
  731. Inc(j);
  732. Result:=Copy(S,1,j-1);
  733. Delete(S,1,j);
  734. end;
  735. end;
  736. Function StringToSet(PropInfo: PPropInfo; const Value: string): Integer;
  737. begin
  738. Result:=StringToSet(PropInfo^.PropType,Value);
  739. end;
  740. Function StringToSet(TypeInfo: PTypeInfo; const Value: string): Integer;
  741. Var
  742. S,T : String;
  743. I : Integer;
  744. PTI : PTypeInfo;
  745. begin
  746. Result:=0;
  747. PTI:=GetTypeData(TypeInfo)^.Comptype;
  748. S:=Value;
  749. I:=1;
  750. If Length(S)>0 then
  751. begin
  752. While (I<=Length(S)) and (S[i] in SetDelim) do
  753. Inc(I);
  754. Delete(S,1,i-1);
  755. end;
  756. While (S<>'') do
  757. begin
  758. T:=GetNextElement(S);
  759. if T<>'' then
  760. begin
  761. I:=GetEnumValue(PTI,T);
  762. if (I<0) then
  763. raise EPropertyError.CreateFmt(SErrUnknownEnumValue, [T]);
  764. Result:=Result or (1 shl i);
  765. end;
  766. end;
  767. end;
  768. Function AlignTypeData(p : PTypeData) : PTypeData;
  769. {$push}
  770. {$packrecords c}
  771. type
  772. TAlignCheck = record
  773. b : byte;
  774. q : qword;
  775. end;
  776. {$pop}
  777. begin
  778. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  779. {$ifdef VER3_0}
  780. Result:=PTypeData(align(p,SizeOf(Pointer)));
  781. {$else VER3_0}
  782. Result:=PTypeData(align(p,PtrInt(@TAlignCheck(nil^).q)))
  783. {$endif VER3_0}
  784. {$else FPC_REQUIRES_PROPER_ALIGNMENT}
  785. Result:=p;
  786. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  787. end;
  788. Function GetTypeData(TypeInfo : PTypeInfo) : PTypeData;
  789. begin
  790. GetTypeData:=AlignTypeData(pointer(TypeInfo)+2+PByte(pointer(TypeInfo)+1)^);
  791. end;
  792. { ---------------------------------------------------------------------
  793. Basic Type information functions.
  794. ---------------------------------------------------------------------}
  795. Function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string) : PPropInfo;
  796. var
  797. hp : PTypeData;
  798. i : longint;
  799. p : shortstring;
  800. pd : ^TPropData;
  801. begin
  802. P:=PropName; // avoid Ansi<->short conversion in a loop
  803. while Assigned(TypeInfo) do
  804. begin
  805. // skip the name
  806. hp:=GetTypeData(Typeinfo);
  807. // the class info rtti the property rtti follows immediatly
  808. pd:=aligntoptr(pointer(pointer(@hp^.UnitName)+Length(hp^.UnitName)+1));
  809. Result:=PPropInfo(@pd^.PropList);
  810. for i:=1 to pd^.PropCount do
  811. begin
  812. // found a property of that name ?
  813. if ShortCompareText(Result^.Name, P) = 0 then
  814. exit;
  815. // skip to next property
  816. Result:=PPropInfo(aligntoptr(pointer(@Result^.Name)+byte(Result^.Name[0])+1));
  817. end;
  818. // parent class
  819. Typeinfo:=hp^.ParentInfo;
  820. end;
  821. Result:=Nil;
  822. end;
  823. Function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string; Akinds : TTypeKinds) : PPropInfo;
  824. begin
  825. Result:=GetPropInfo(TypeInfo,PropName);
  826. If (Akinds<>[]) then
  827. If (Result<>Nil) then
  828. If Not (Result^.PropType^.Kind in AKinds) then
  829. Result:=Nil;
  830. end;
  831. Function GetPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds) : PPropInfo;
  832. begin
  833. Result:=GetPropInfo(PTypeInfo(AClass.ClassInfo),PropName,AKinds);
  834. end;
  835. Function GetPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds) : PPropInfo;
  836. begin
  837. Result:=GetPropInfo(Instance.ClassType,PropName,AKinds);
  838. end;
  839. Function GetPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  840. begin
  841. Result:=GetPropInfo(Instance,PropName,[]);
  842. end;
  843. Function GetPropInfo(AClass: TClass; const PropName: string): PPropInfo;
  844. begin
  845. Result:=GetPropInfo(AClass,PropName,[]);
  846. end;
  847. Function FindPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  848. begin
  849. result:=GetPropInfo(Instance, PropName);
  850. if Result=nil then
  851. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  852. end;
  853. Function FindPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  854. begin
  855. result:=GetPropInfo(Instance, PropName, AKinds);
  856. if Result=nil then
  857. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  858. end;
  859. Function FindPropInfo(AClass: TClass; const PropName: string): PPropInfo;
  860. begin
  861. result:=GetPropInfo(AClass, PropName);
  862. if result=nil then
  863. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  864. end;
  865. Function FindPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  866. begin
  867. result:=GetPropInfo(AClass, PropName, AKinds);
  868. if result=nil then
  869. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  870. end;
  871. Function IsStoredProp(Instance : TObject;PropInfo : PPropInfo) : Boolean;
  872. type
  873. TBooleanIndexFunc=function(Index:integer):boolean of object;
  874. TBooleanFunc=function:boolean of object;
  875. var
  876. AMethod : TMethod;
  877. begin
  878. case (PropInfo^.PropProcs shr 4) and 3 of
  879. ptField:
  880. Result:=PBoolean(Pointer(Instance)+PtrUInt(PropInfo^.StoredProc))^;
  881. ptConst:
  882. Result:=LongBool(PropInfo^.StoredProc);
  883. ptStatic,
  884. ptVirtual:
  885. begin
  886. if (PropInfo^.PropProcs shr 4) and 3=ptstatic then
  887. AMethod.Code:=PropInfo^.StoredProc
  888. else
  889. AMethod.Code:=pcodepointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.StoredProc))^;
  890. AMethod.Data:=Instance;
  891. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  892. Result:=TBooleanIndexFunc(AMethod)(PropInfo^.Index)
  893. else
  894. Result:=TBooleanFunc(AMethod)();
  895. end;
  896. end;
  897. end;
  898. Procedure GetPropInfos(TypeInfo : PTypeInfo;PropList : PPropList);
  899. {
  900. Store Pointers to property information in the list pointed
  901. to by proplist. PRopList must contain enough space to hold ALL
  902. properties.
  903. }
  904. Var
  905. TD : PTypeData;
  906. TP : PPropInfo;
  907. Count : Longint;
  908. begin
  909. // Get this objects TOTAL published properties count
  910. TD:=GetTypeData(TypeInfo);
  911. // Clear list
  912. FillChar(PropList^,TD^.PropCount*sizeof(Pointer),0);
  913. repeat
  914. TD:=GetTypeData(TypeInfo);
  915. // published properties count for this object
  916. TP:=aligntoptr(PPropInfo(aligntoptr((Pointer(@TD^.UnitName)+Length(TD^.UnitName)+1))));
  917. Count:=PWord(TP)^;
  918. // Now point TP to first propinfo record.
  919. Inc(Pointer(TP),SizeOF(Word));
  920. tp:=aligntoptr(tp);
  921. While Count>0 do
  922. begin
  923. // Don't overwrite properties with the same name
  924. if PropList^[TP^.NameIndex]=nil then
  925. PropList^[TP^.NameIndex]:=TP;
  926. // Point to TP next propinfo record.
  927. // Located at Name[Length(Name)+1] !
  928. TP:=aligntoptr(PPropInfo(pointer(@TP^.Name)+PByte(@TP^.Name)^+1));
  929. Dec(Count);
  930. end;
  931. TypeInfo:=TD^.Parentinfo;
  932. until TypeInfo=nil;
  933. end;
  934. Procedure InsertProp (PL : PProplist;PI : PPropInfo; Count : longint);
  935. Var
  936. I : Longint;
  937. begin
  938. I:=0;
  939. While (I<Count) and (PI^.Name>PL^[I]^.Name) do
  940. Inc(I);
  941. If I<Count then
  942. Move(PL^[I], PL^[I+1], (Count - I) * SizeOf(Pointer));
  943. PL^[I]:=PI;
  944. end;
  945. Procedure InsertPropnosort (PL : PProplist;PI : PPropInfo; Count : longint);
  946. begin
  947. PL^[Count]:=PI;
  948. end;
  949. Type TInsertProp = Procedure (PL : PProplist;PI : PPropInfo; Count : longint);
  950. //Const InsertProps : array[false..boolean] of TInsertProp = (InsertPropNoSort,InsertProp);
  951. Function GetPropList(TypeInfo : PTypeInfo;TypeKinds : TTypeKinds; PropList : PPropList;Sorted : boolean = true):longint;
  952. {
  953. Store Pointers to property information OF A CERTAIN KIND in the list pointed
  954. to by proplist. PRopList must contain enough space to hold ALL
  955. properties.
  956. }
  957. Var
  958. TempList : PPropList;
  959. PropInfo : PPropinfo;
  960. I,Count : longint;
  961. DoInsertProp : TInsertProp;
  962. begin
  963. if sorted then
  964. DoInsertProp:=@InsertProp
  965. else
  966. DoInsertProp:=@InsertPropnosort;
  967. Result:=0;
  968. Count:=GetTypeData(TypeInfo)^.Propcount;
  969. If Count>0 then
  970. begin
  971. GetMem(TempList,Count*SizeOf(Pointer));
  972. Try
  973. GetPropInfos(TypeInfo,TempList);
  974. For I:=0 to Count-1 do
  975. begin
  976. PropInfo:=TempList^[i];
  977. If PropInfo^.PropType^.Kind in TypeKinds then
  978. begin
  979. If (PropList<>Nil) then
  980. DoInsertProp(PropList,PropInfo,Result);
  981. Inc(Result);
  982. end;
  983. end;
  984. finally
  985. FreeMem(TempList,Count*SizeOf(Pointer));
  986. end;
  987. end;
  988. end;
  989. Function GetPropList(TypeInfo: PTypeInfo; out PropList: PPropList): SizeInt;
  990. begin
  991. result:=GetTypeData(TypeInfo)^.Propcount;
  992. if result>0 then
  993. begin
  994. getmem(PropList,result*sizeof(pointer));
  995. GetPropInfos(TypeInfo,PropList);
  996. end
  997. else
  998. PropList:=Nil;
  999. end;
  1000. function GetPropList(AClass: TClass; out PropList: PPropList): Integer;
  1001. begin
  1002. Result := GetPropList(PTypeInfo(AClass.ClassInfo), PropList);
  1003. end;
  1004. function GetPropList(Instance: TObject; out PropList: PPropList): Integer;
  1005. begin
  1006. Result := GetPropList(Instance.ClassType, PropList);
  1007. end;
  1008. { ---------------------------------------------------------------------
  1009. Property access functions
  1010. ---------------------------------------------------------------------}
  1011. { ---------------------------------------------------------------------
  1012. Ordinal properties
  1013. ---------------------------------------------------------------------}
  1014. Function GetOrdProp(Instance : TObject;PropInfo : PPropInfo) : Int64;
  1015. type
  1016. TGetInt64ProcIndex=function(index:longint):Int64 of object;
  1017. TGetInt64Proc=function():Int64 of object;
  1018. TGetIntegerProcIndex=function(index:longint):longint of object;
  1019. TGetIntegerProc=function:longint of object;
  1020. TGetWordProcIndex=function(index:longint):word of object;
  1021. TGetWordProc=function:word of object;
  1022. TGetByteProcIndex=function(index:longint):Byte of object;
  1023. TGetByteProc=function:Byte of object;
  1024. var
  1025. TypeInfo: PTypeInfo;
  1026. AMethod : TMethod;
  1027. DataSize: Integer;
  1028. OrdType: TOrdType;
  1029. Signed: Boolean;
  1030. begin
  1031. Result:=0;
  1032. TypeInfo := PropInfo^.PropType;
  1033. Signed := false;
  1034. DataSize := 4;
  1035. case TypeInfo^.Kind of
  1036. {$ifdef cpu64}
  1037. tkInterface,
  1038. tkInterfaceRaw,
  1039. tkDynArray,
  1040. tkClass:
  1041. DataSize:=8;
  1042. {$endif cpu64}
  1043. tkChar, tkBool:
  1044. DataSize:=1;
  1045. tkWChar:
  1046. DataSize:=2;
  1047. tkSet,
  1048. tkEnumeration,
  1049. tkInteger:
  1050. begin
  1051. OrdType:=GetTypeData(TypeInfo)^.OrdType;
  1052. case OrdType of
  1053. otSByte,otUByte: DataSize := 1;
  1054. otSWord,otUWord: DataSize := 2;
  1055. end;
  1056. Signed := OrdType in [otSByte,otSWord,otSLong];
  1057. end;
  1058. tkInt64 :
  1059. begin
  1060. DataSize:=8;
  1061. Signed:=true;
  1062. end;
  1063. tkQword :
  1064. begin
  1065. DataSize:=8;
  1066. Signed:=false;
  1067. end;
  1068. end;
  1069. case (PropInfo^.PropProcs) and 3 of
  1070. ptField:
  1071. if Signed then begin
  1072. case DataSize of
  1073. 1: Result:=PShortInt(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1074. 2: Result:=PSmallInt(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1075. 4: Result:=PLongint(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1076. 8: Result:=PInt64(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1077. end;
  1078. end else begin
  1079. case DataSize of
  1080. 1: Result:=PByte(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1081. 2: Result:=PWord(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1082. 4: Result:=PLongint(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1083. 8: Result:=PInt64(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1084. end;
  1085. end;
  1086. ptStatic,
  1087. ptVirtual:
  1088. begin
  1089. if (PropInfo^.PropProcs and 3)=ptStatic then
  1090. AMethod.Code:=PropInfo^.GetProc
  1091. else
  1092. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1093. AMethod.Data:=Instance;
  1094. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then begin
  1095. case DataSize of
  1096. 1: Result:=TGetByteProcIndex(AMethod)(PropInfo^.Index);
  1097. 2: Result:=TGetWordProcIndex(AMethod)(PropInfo^.Index);
  1098. 4: Result:=TGetIntegerProcIndex(AMethod)(PropInfo^.Index);
  1099. 8: result:=TGetInt64ProcIndex(AMethod)(PropInfo^.Index)
  1100. end;
  1101. end else begin
  1102. case DataSize of
  1103. 1: Result:=TGetByteProc(AMethod)();
  1104. 2: Result:=TGetWordProc(AMethod)();
  1105. 4: Result:=TGetIntegerProc(AMethod)();
  1106. 8: result:=TGetInt64Proc(AMethod)();
  1107. end;
  1108. end;
  1109. if Signed then begin
  1110. case DataSize of
  1111. 1: Result:=ShortInt(Result);
  1112. 2: Result:=SmallInt(Result);
  1113. end;
  1114. end;
  1115. end;
  1116. end;
  1117. end;
  1118. Procedure SetOrdProp(Instance : TObject;PropInfo : PPropInfo;Value : Int64);
  1119. type
  1120. TSetInt64ProcIndex=procedure(index:longint;i:Int64) of object;
  1121. TSetInt64Proc=procedure(i:Int64) of object;
  1122. TSetIntegerProcIndex=procedure(index,i:longint) of object;
  1123. TSetIntegerProc=procedure(i:longint) of object;
  1124. var
  1125. DataSize: Integer;
  1126. AMethod : TMethod;
  1127. begin
  1128. if PropInfo^.PropType^.Kind in [tkInt64,tkQword
  1129. { why do we have to handle classes here, see also below? (FK) }
  1130. {$ifdef cpu64}
  1131. ,tkInterface
  1132. ,tkInterfaceRaw
  1133. ,tkDynArray
  1134. ,tkClass
  1135. {$endif cpu64}
  1136. ] then
  1137. DataSize := 8
  1138. else
  1139. DataSize := 4;
  1140. if not(PropInfo^.PropType^.Kind in [tkInt64,tkQword,tkClass,tkInterface,tkInterfaceRaw,tkDynArray]) then
  1141. begin
  1142. { cut off unnecessary stuff }
  1143. case GetTypeData(PropInfo^.PropType)^.OrdType of
  1144. otSWord,otUWord:
  1145. begin
  1146. Value:=Value and $ffff;
  1147. DataSize := 2;
  1148. end;
  1149. otSByte,otUByte:
  1150. begin
  1151. Value:=Value and $ff;
  1152. DataSize := 1;
  1153. end;
  1154. end;
  1155. end;
  1156. case (PropInfo^.PropProcs shr 2) and 3 of
  1157. ptField:
  1158. case DataSize of
  1159. 1: PByte(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Byte(Value);
  1160. 2: PWord(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Word(Value);
  1161. 4: PLongint(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Longint(Value);
  1162. 8: PInt64(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1163. end;
  1164. ptStatic,
  1165. ptVirtual:
  1166. begin
  1167. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1168. AMethod.Code:=PropInfo^.SetProc
  1169. else
  1170. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1171. AMethod.Data:=Instance;
  1172. if datasize=8 then
  1173. begin
  1174. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1175. TSetInt64ProcIndex(AMethod)(PropInfo^.Index,Value)
  1176. else
  1177. TSetInt64Proc(AMethod)(Value);
  1178. end
  1179. else
  1180. begin
  1181. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1182. TSetIntegerProcIndex(AMethod)(PropInfo^.Index,Value)
  1183. else
  1184. TSetIntegerProc(AMethod)(Value);
  1185. end;
  1186. end;
  1187. end;
  1188. end;
  1189. Function GetOrdProp(Instance: TObject; const PropName: string): Int64;
  1190. begin
  1191. Result:=GetOrdProp(Instance,FindPropInfo(Instance,PropName));
  1192. end;
  1193. Procedure SetOrdProp(Instance: TObject; const PropName: string; Value: Int64);
  1194. begin
  1195. SetOrdProp(Instance,FindPropInfo(Instance,PropName),Value);
  1196. end;
  1197. Function GetEnumProp(Instance: TObject; Const PropInfo: PPropInfo): string;
  1198. begin
  1199. Result:=GetEnumName(PropInfo^.PropType, GetOrdProp(Instance, PropInfo));
  1200. end;
  1201. Function GetEnumProp(Instance: TObject; const PropName: string): string;
  1202. begin
  1203. Result:=GetEnumProp(Instance,FindPropInfo(Instance,PropName));
  1204. end;
  1205. Procedure SetEnumProp(Instance: TObject; const PropName: string; const Value: string);
  1206. begin
  1207. SetEnumProp(Instance,FindPropInfo(Instance,PropName),Value);
  1208. end;
  1209. Procedure SetEnumProp(Instance: TObject; Const PropInfo : PPropInfo; const Value: string);
  1210. Var
  1211. PV : Longint;
  1212. begin
  1213. If PropInfo<>Nil then
  1214. begin
  1215. PV:=GetEnumValue(PropInfo^.PropType, Value);
  1216. if (PV<0) then
  1217. raise EPropertyError.CreateFmt(SErrUnknownEnumValue, [Value]);
  1218. SetOrdProp(Instance, PropInfo,PV);
  1219. end;
  1220. end;
  1221. { ---------------------------------------------------------------------
  1222. Int64 wrappers
  1223. ---------------------------------------------------------------------}
  1224. Function GetInt64Prop(Instance: TObject; PropInfo: PPropInfo): Int64;
  1225. begin
  1226. Result:=GetOrdProp(Instance,PropInfo);
  1227. end;
  1228. procedure SetInt64Prop(Instance: TObject; PropInfo: PPropInfo; const Value: Int64);
  1229. begin
  1230. SetOrdProp(Instance,PropInfo,Value);
  1231. end;
  1232. Function GetInt64Prop(Instance: TObject; const PropName: string): Int64;
  1233. begin
  1234. Result:=GetInt64Prop(Instance,FindPropInfo(Instance,PropName));
  1235. end;
  1236. Procedure SetInt64Prop(Instance: TObject; const PropName: string; const Value: Int64);
  1237. begin
  1238. SetInt64Prop(Instance,FindPropInfo(Instance,PropName),Value);
  1239. end;
  1240. { ---------------------------------------------------------------------
  1241. Set properties
  1242. ---------------------------------------------------------------------}
  1243. Function GetSetProp(Instance: TObject; const PropName: string): string;
  1244. begin
  1245. Result:=GetSetProp(Instance,PropName,False);
  1246. end;
  1247. Function GetSetProp(Instance: TObject; const PropName: string; Brackets: Boolean): string;
  1248. begin
  1249. Result:=GetSetProp(Instance,FindPropInfo(Instance,PropName),Brackets);
  1250. end;
  1251. Function GetSetProp(Instance: TObject; const PropInfo: PPropInfo; Brackets: Boolean): string;
  1252. begin
  1253. Result:=SetToString(PropInfo,GetOrdProp(Instance,PropInfo),Brackets);
  1254. end;
  1255. Procedure SetSetProp(Instance: TObject; const PropName: string; const Value: string);
  1256. begin
  1257. SetSetProp(Instance,FindPropInfo(Instance,PropName),Value);
  1258. end;
  1259. Procedure SetSetProp(Instance: TObject; const PropInfo: PPropInfo; const Value: string);
  1260. begin
  1261. SetOrdProp(Instance,PropInfo,StringToSet(PropInfo,Value));
  1262. end;
  1263. { ---------------------------------------------------------------------
  1264. Object properties
  1265. ---------------------------------------------------------------------}
  1266. Function GetObjectProp(Instance: TObject; const PropName: string): TObject;
  1267. begin
  1268. Result:=GetObjectProp(Instance,PropName,Nil);
  1269. end;
  1270. Function GetObjectProp(Instance: TObject; const PropName: string; MinClass: TClass): TObject;
  1271. begin
  1272. Result:=GetObjectProp(Instance,FindPropInfo(Instance,PropName),MinClass);
  1273. end;
  1274. Function GetObjectProp(Instance: TObject; PropInfo : PPropInfo): TObject;
  1275. begin
  1276. Result:=GetObjectProp(Instance,PropInfo,Nil);
  1277. end;
  1278. Function GetObjectProp(Instance: TObject; PropInfo : PPropInfo; MinClass: TClass): TObject;
  1279. begin
  1280. {$ifdef cpu64}
  1281. Result:=TObject(GetInt64Prop(Instance,PropInfo));
  1282. {$else cpu64}
  1283. Result:=TObject(PtrInt(GetOrdProp(Instance,PropInfo)));
  1284. {$endif cpu64}
  1285. If (MinClass<>Nil) and (Result<>Nil) Then
  1286. If Not Result.InheritsFrom(MinClass) then
  1287. Result:=Nil;
  1288. end;
  1289. Procedure SetObjectProp(Instance: TObject; const PropName: string; Value: TObject);
  1290. begin
  1291. SetObjectProp(Instance,FindPropInfo(Instance,PropName),Value);
  1292. end;
  1293. Procedure SetObjectProp(Instance: TObject; PropInfo : PPropInfo; Value: TObject);
  1294. begin
  1295. {$ifdef cpu64}
  1296. SetInt64Prop(Instance,PropInfo,Int64(Value));
  1297. {$else cpu64}
  1298. SetOrdProp(Instance,PropInfo,PtrInt(Value));
  1299. {$endif cpu64}
  1300. end;
  1301. Function GetObjectPropClass(Instance: TObject; const PropName: string): TClass;
  1302. begin
  1303. Result:=GetTypeData(FindPropInfo(Instance,PropName,[tkClass])^.PropType)^.ClassType;
  1304. end;
  1305. Function GetObjectPropClass(AClass: TClass; const PropName: string): TClass;
  1306. begin
  1307. Result:=GetTypeData(FindPropInfo(AClass,PropName,[tkClass])^.PropType)^.ClassType;
  1308. end;
  1309. { ---------------------------------------------------------------------
  1310. Interface wrapprers
  1311. ---------------------------------------------------------------------}
  1312. function GetInterfaceProp(Instance: TObject; const PropName: string): IInterface;
  1313. begin
  1314. Result:=GetInterfaceProp(Instance,FindPropInfo(Instance,PropName));
  1315. end;
  1316. function GetInterfaceProp(Instance: TObject; PropInfo: PPropInfo): IInterface;
  1317. type
  1318. TGetInterfaceProc=function:IInterface of object;
  1319. TGetInterfaceProcIndex=function(index:longint):IInterface of object;
  1320. var
  1321. AMethod : TMethod;
  1322. begin
  1323. Result:=nil;
  1324. case (PropInfo^.PropProcs) and 3 of
  1325. ptField:
  1326. Result:=IInterface(PPointer(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^);
  1327. ptStatic,
  1328. ptVirtual:
  1329. begin
  1330. if (PropInfo^.PropProcs and 3)=ptStatic then
  1331. AMethod.Code:=PropInfo^.GetProc
  1332. else
  1333. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1334. AMethod.Data:=Instance;
  1335. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1336. Result:=TGetInterfaceProcIndex(AMethod)(PropInfo^.Index)
  1337. else
  1338. Result:=TGetInterfaceProc(AMethod)();
  1339. end;
  1340. end;
  1341. end;
  1342. procedure SetInterfaceProp(Instance: TObject; const PropName: string; const Value: IInterface);
  1343. begin
  1344. SetInterfaceProp(Instance,FindPropInfo(Instance,PropName),Value);
  1345. end;
  1346. procedure SetInterfaceProp(Instance: TObject; PropInfo: PPropInfo; const Value: IInterface);
  1347. type
  1348. TSetIntfStrProcIndex=procedure(index:longint;const i:IInterface) of object;
  1349. TSetIntfStrProc=procedure(i:IInterface) of object;
  1350. var
  1351. AMethod : TMethod;
  1352. begin
  1353. case Propinfo^.PropType^.Kind of
  1354. tkInterface:
  1355. begin
  1356. case (PropInfo^.PropProcs shr 2) and 3 of
  1357. ptField:
  1358. PInterface(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1359. ptStatic,
  1360. ptVirtual:
  1361. begin
  1362. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1363. AMethod.Code:=PropInfo^.SetProc
  1364. else
  1365. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1366. AMethod.Data:=Instance;
  1367. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1368. TSetIntfStrProcIndex(AMethod)(PropInfo^.Index,Value)
  1369. else
  1370. TSetIntfStrProc(AMethod)(Value);
  1371. end;
  1372. end;
  1373. end;
  1374. tkInterfaceRaw:
  1375. Raise Exception.Create('Cannot set RAW interface from IUnknown interface');
  1376. end;
  1377. end;
  1378. { ---------------------------------------------------------------------
  1379. RAW (Corba) Interface wrapprers
  1380. ---------------------------------------------------------------------}
  1381. function GetRawInterfaceProp(Instance: TObject; const PropName: string): Pointer;
  1382. begin
  1383. Result:=GetRawInterfaceProp(Instance,FindPropInfo(Instance,PropName));
  1384. end;
  1385. function GetRawInterfaceProp(Instance: TObject; PropInfo: PPropInfo): Pointer;
  1386. begin
  1387. {$ifdef cpu64}
  1388. Result:=Pointer(GetInt64Prop(Instance,PropInfo));
  1389. {$else cpu64}
  1390. Result:=Pointer(PtrInt(GetOrdProp(Instance,PropInfo)));
  1391. {$endif cpu64}
  1392. end;
  1393. procedure SetRawInterfaceProp(Instance: TObject; const PropName: string; const Value: Pointer);
  1394. begin
  1395. SetRawInterfaceProp(Instance,FindPropInfo(Instance,PropName),Value);
  1396. end;
  1397. procedure SetRawInterfaceProp(Instance: TObject; PropInfo: PPropInfo; const Value: Pointer);
  1398. type
  1399. TSetPointerProcIndex=procedure(index:longint;const i:Pointer) of object;
  1400. TSetPointerProc=procedure(i:Pointer) of object;
  1401. var
  1402. AMethod : TMethod;
  1403. begin
  1404. case Propinfo^.PropType^.Kind of
  1405. tkInterfaceRaw:
  1406. begin
  1407. case (PropInfo^.PropProcs shr 2) and 3 of
  1408. ptField:
  1409. PPointer(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1410. ptStatic,
  1411. ptVirtual:
  1412. begin
  1413. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1414. AMethod.Code:=PropInfo^.SetProc
  1415. else
  1416. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1417. AMethod.Data:=Instance;
  1418. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1419. TSetPointerProcIndex(AMethod)(PropInfo^.Index,Value)
  1420. else
  1421. TSetPointerProc(AMethod)(Value);
  1422. end;
  1423. end;
  1424. end;
  1425. tkInterface:
  1426. Raise Exception.Create('Cannot set interface from RAW interface');
  1427. end;
  1428. end;
  1429. { ---------------------------------------------------------------------
  1430. Dynamic array properties
  1431. ---------------------------------------------------------------------}
  1432. function GetDynArrayProp(Instance: TObject; const PropName: string): Pointer;
  1433. begin
  1434. Result:=GetDynArrayProp(Instance,FindPropInfo(Instance,PropName));
  1435. end;
  1436. function GetDynArrayProp(Instance: TObject; PropInfo: PPropInfo): Pointer;
  1437. type
  1438. { we need a dynamic array as that type is usually passed differently from
  1439. a plain pointer }
  1440. TDynArray=array of Byte;
  1441. TGetDynArrayProc=function:TDynArray of object;
  1442. TGetDynArrayProcIndex=function(index:longint):TDynArray of object;
  1443. var
  1444. AMethod : TMethod;
  1445. begin
  1446. Result:=nil;
  1447. if PropInfo^.PropType^.Kind<>tkDynArray then
  1448. Exit;
  1449. case (PropInfo^.PropProcs) and 3 of
  1450. ptField:
  1451. Result:=PPointer(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1452. ptStatic,
  1453. ptVirtual:
  1454. begin
  1455. if (PropInfo^.PropProcs and 3)=ptStatic then
  1456. AMethod.Code:=PropInfo^.GetProc
  1457. else
  1458. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1459. AMethod.Data:=Instance;
  1460. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1461. Result:=Pointer(TGetDynArrayProcIndex(AMethod)(PropInfo^.Index))
  1462. else
  1463. Result:=Pointer(TGetDynArrayProc(AMethod)());
  1464. end;
  1465. end;
  1466. end;
  1467. procedure SetDynArrayProp(Instance: TObject; const PropName: string; const Value: Pointer);
  1468. begin
  1469. SetDynArrayProp(Instance,FindPropInfo(Instance,PropName),Value);
  1470. end;
  1471. procedure SetDynArrayProp(Instance: TObject; PropInfo: PPropInfo; const Value: Pointer);
  1472. type
  1473. { we need a dynamic array as that type is usually passed differently from
  1474. a plain pointer }
  1475. TDynArray=array of Byte;
  1476. TSetDynArrayProcIndex=procedure(index:longint;const i:TDynArray) of object;
  1477. TSetDynArrayProc=procedure(i:TDynArray) of object;
  1478. var
  1479. AMethod: TMethod;
  1480. begin
  1481. if PropInfo^.PropType^.Kind<>tkDynArray then
  1482. Exit;
  1483. case (PropInfo^.PropProcs shr 2) and 3 of
  1484. ptField:
  1485. CopyArray(PPointer(Pointer(Instance)+PtrUInt(PropInfo^.SetProc)), @Value, PropInfo^.PropType, 1);
  1486. ptStatic,
  1487. ptVirtual:
  1488. begin
  1489. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1490. AMethod.Code:=PropInfo^.SetProc
  1491. else
  1492. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1493. AMethod.Data:=Instance;
  1494. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1495. TSetDynArrayProcIndex(AMethod)(PropInfo^.Index,TDynArray(Value))
  1496. else
  1497. TSetDynArrayProc(AMethod)(TDynArray(Value));
  1498. end;
  1499. end;
  1500. end;
  1501. { ---------------------------------------------------------------------
  1502. String properties
  1503. ---------------------------------------------------------------------}
  1504. Function GetStrProp(Instance: TObject; PropInfo: PPropInfo): AnsiString;
  1505. type
  1506. TGetShortStrProcIndex=function(index:longint):ShortString of object;
  1507. TGetShortStrProc=function():ShortString of object;
  1508. TGetAnsiStrProcIndex=function(index:longint):AnsiString of object;
  1509. TGetAnsiStrProc=function():AnsiString of object;
  1510. var
  1511. AMethod : TMethod;
  1512. begin
  1513. Result:='';
  1514. case Propinfo^.PropType^.Kind of
  1515. tkWString:
  1516. Result:=AnsiString(GetWideStrProp(Instance,PropInfo));
  1517. tkUString:
  1518. Result := AnsiString(GetUnicodeStrProp(Instance,PropInfo));
  1519. tkSString:
  1520. begin
  1521. case (PropInfo^.PropProcs) and 3 of
  1522. ptField:
  1523. Result := PShortString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  1524. ptStatic,
  1525. ptVirtual:
  1526. begin
  1527. if (PropInfo^.PropProcs and 3)=ptStatic then
  1528. AMethod.Code:=PropInfo^.GetProc
  1529. else
  1530. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1531. AMethod.Data:=Instance;
  1532. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1533. Result:=TGetShortStrProcIndex(AMethod)(PropInfo^.Index)
  1534. else
  1535. Result:=TGetShortStrProc(AMethod)();
  1536. end;
  1537. end;
  1538. end;
  1539. tkAString:
  1540. begin
  1541. case (PropInfo^.PropProcs) and 3 of
  1542. ptField:
  1543. Result := PAnsiString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  1544. ptStatic,
  1545. ptVirtual:
  1546. begin
  1547. if (PropInfo^.PropProcs and 3)=ptStatic then
  1548. AMethod.Code:=PropInfo^.GetProc
  1549. else
  1550. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1551. AMethod.Data:=Instance;
  1552. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1553. Result:=TGetAnsiStrProcIndex(AMethod)(PropInfo^.Index)
  1554. else
  1555. Result:=TGetAnsiStrProc(AMethod)();
  1556. end;
  1557. end;
  1558. end;
  1559. end;
  1560. end;
  1561. Procedure SetStrProp(Instance : TObject;PropInfo : PPropInfo; const Value : AnsiString);
  1562. type
  1563. TSetShortStrProcIndex=procedure(index:longint;const s:ShortString) of object;
  1564. TSetShortStrProc=procedure(const s:ShortString) of object;
  1565. TSetAnsiStrProcIndex=procedure(index:longint;s:AnsiString) of object;
  1566. TSetAnsiStrProc=procedure(s:AnsiString) of object;
  1567. var
  1568. AMethod : TMethod;
  1569. begin
  1570. case Propinfo^.PropType^.Kind of
  1571. tkWString:
  1572. SetWideStrProp(Instance,PropInfo,WideString(Value));
  1573. tkUString:
  1574. SetUnicodeStrProp(Instance,PropInfo,UnicodeString(Value));
  1575. tkSString:
  1576. begin
  1577. case (PropInfo^.PropProcs shr 2) and 3 of
  1578. ptField:
  1579. PShortString(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  1580. ptStatic,
  1581. ptVirtual:
  1582. begin
  1583. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1584. AMethod.Code:=PropInfo^.SetProc
  1585. else
  1586. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1587. AMethod.Data:=Instance;
  1588. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1589. TSetShortStrProcIndex(AMethod)(PropInfo^.Index,Value)
  1590. else
  1591. TSetShortStrProc(AMethod)(Value);
  1592. end;
  1593. end;
  1594. end;
  1595. tkAString:
  1596. begin
  1597. case (PropInfo^.PropProcs shr 2) and 3 of
  1598. ptField:
  1599. PAnsiString(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  1600. ptStatic,
  1601. ptVirtual:
  1602. begin
  1603. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1604. AMethod.Code:=PropInfo^.SetProc
  1605. else
  1606. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1607. AMethod.Data:=Instance;
  1608. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1609. TSetAnsiStrProcIndex(AMethod)(PropInfo^.Index,Value)
  1610. else
  1611. TSetAnsiStrProc(AMethod)(Value);
  1612. end;
  1613. end;
  1614. end;
  1615. end;
  1616. end;
  1617. Function GetStrProp(Instance: TObject; const PropName: string): string;
  1618. begin
  1619. Result:=GetStrProp(Instance,FindPropInfo(Instance,PropName));
  1620. end;
  1621. Procedure SetStrProp(Instance: TObject; const PropName: string; const Value: AnsiString);
  1622. begin
  1623. SetStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  1624. end;
  1625. Function GetWideStrProp(Instance: TObject; const PropName: string): WideString;
  1626. begin
  1627. Result:=GetWideStrProp(Instance, FindPropInfo(Instance, PropName));
  1628. end;
  1629. procedure SetWideStrProp(Instance: TObject; const PropName: string; const Value: WideString);
  1630. begin
  1631. SetWideStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  1632. end;
  1633. Function GetWideStrProp(Instance: TObject; PropInfo: PPropInfo): WideString;
  1634. type
  1635. TGetWideStrProcIndex=function(index:longint):WideString of object;
  1636. TGetWideStrProc=function():WideString of object;
  1637. var
  1638. AMethod : TMethod;
  1639. begin
  1640. Result:='';
  1641. case Propinfo^.PropType^.Kind of
  1642. tkSString,tkAString:
  1643. Result:=WideString(GetStrProp(Instance,PropInfo));
  1644. tkUString :
  1645. Result := GetUnicodeStrProp(Instance,PropInfo);
  1646. tkWString:
  1647. begin
  1648. case (PropInfo^.PropProcs) and 3 of
  1649. ptField:
  1650. Result := PWideString(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1651. ptStatic,
  1652. ptVirtual:
  1653. begin
  1654. if (PropInfo^.PropProcs and 3)=ptStatic then
  1655. AMethod.Code:=PropInfo^.GetProc
  1656. else
  1657. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1658. AMethod.Data:=Instance;
  1659. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1660. Result:=TGetWideStrProcIndex(AMethod)(PropInfo^.Index)
  1661. else
  1662. Result:=TGetWideStrProc(AMethod)();
  1663. end;
  1664. end;
  1665. end;
  1666. end;
  1667. end;
  1668. Procedure SetWideStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: WideString);
  1669. type
  1670. TSetWideStrProcIndex=procedure(index:longint;s:WideString) of object;
  1671. TSetWideStrProc=procedure(s:WideString) of object;
  1672. var
  1673. AMethod : TMethod;
  1674. begin
  1675. case Propinfo^.PropType^.Kind of
  1676. tkSString,tkAString:
  1677. SetStrProp(Instance,PropInfo,AnsiString(Value));
  1678. tkUString:
  1679. SetUnicodeStrProp(Instance,PropInfo,Value);
  1680. tkWString:
  1681. begin
  1682. case (PropInfo^.PropProcs shr 2) and 3 of
  1683. ptField:
  1684. PWideString(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1685. ptStatic,
  1686. ptVirtual:
  1687. begin
  1688. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1689. AMethod.Code:=PropInfo^.SetProc
  1690. else
  1691. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1692. AMethod.Data:=Instance;
  1693. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1694. TSetWideStrProcIndex(AMethod)(PropInfo^.Index,Value)
  1695. else
  1696. TSetWideStrProc(AMethod)(Value);
  1697. end;
  1698. end;
  1699. end;
  1700. end;
  1701. end;
  1702. Function GetUnicodeStrProp(Instance: TObject; const PropName: string): UnicodeString;
  1703. begin
  1704. Result:=GetUnicodeStrProp(Instance, FindPropInfo(Instance, PropName));
  1705. end;
  1706. procedure SetUnicodeStrProp(Instance: TObject; const PropName: string; const Value: UnicodeString);
  1707. begin
  1708. SetUnicodeStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  1709. end;
  1710. Function GetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo): UnicodeString;
  1711. type
  1712. TGetUnicodeStrProcIndex=function(index:longint):UnicodeString of object;
  1713. TGetUnicodeStrProc=function():UnicodeString of object;
  1714. var
  1715. AMethod : TMethod;
  1716. begin
  1717. Result:='';
  1718. case Propinfo^.PropType^.Kind of
  1719. tkSString,tkAString:
  1720. Result:=UnicodeString(GetStrProp(Instance,PropInfo));
  1721. tkWString:
  1722. Result:=GetWideStrProp(Instance,PropInfo);
  1723. tkUString:
  1724. begin
  1725. case (PropInfo^.PropProcs) and 3 of
  1726. ptField:
  1727. Result := PUnicodeString(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1728. ptStatic,
  1729. ptVirtual:
  1730. begin
  1731. if (PropInfo^.PropProcs and 3)=ptStatic then
  1732. AMethod.Code:=PropInfo^.GetProc
  1733. else
  1734. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1735. AMethod.Data:=Instance;
  1736. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1737. Result:=TGetUnicodeStrProcIndex(AMethod)(PropInfo^.Index)
  1738. else
  1739. Result:=TGetUnicodeStrProc(AMethod)();
  1740. end;
  1741. end;
  1742. end;
  1743. end;
  1744. end;
  1745. Procedure SetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: UnicodeString);
  1746. type
  1747. TSetUnicodeStrProcIndex=procedure(index:longint;s:UnicodeString) of object;
  1748. TSetUnicodeStrProc=procedure(s:UnicodeString) of object;
  1749. var
  1750. AMethod : TMethod;
  1751. begin
  1752. case Propinfo^.PropType^.Kind of
  1753. tkSString,tkAString:
  1754. SetStrProp(Instance,PropInfo,AnsiString(Value));
  1755. tkWString:
  1756. SetWideStrProp(Instance,PropInfo,Value);
  1757. tkUString:
  1758. begin
  1759. case (PropInfo^.PropProcs shr 2) and 3 of
  1760. ptField:
  1761. PUnicodeString(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1762. ptStatic,
  1763. ptVirtual:
  1764. begin
  1765. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1766. AMethod.Code:=PropInfo^.SetProc
  1767. else
  1768. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1769. AMethod.Data:=Instance;
  1770. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1771. TSetUnicodeStrProcIndex(AMethod)(PropInfo^.Index,Value)
  1772. else
  1773. TSetUnicodeStrProc(AMethod)(Value);
  1774. end;
  1775. end;
  1776. end;
  1777. end;
  1778. end;
  1779. {$ifndef FPUNONE}
  1780. { ---------------------------------------------------------------------
  1781. Float properties
  1782. ---------------------------------------------------------------------}
  1783. function GetFloatProp(Instance : TObject;PropInfo : PPropInfo) : Extended;
  1784. type
  1785. TGetExtendedProc = function:Extended of object;
  1786. TGetExtendedProcIndex = function(Index: integer): Extended of object;
  1787. TGetDoubleProc = function:Double of object;
  1788. TGetDoubleProcIndex = function(Index: integer): Double of object;
  1789. TGetSingleProc = function:Single of object;
  1790. TGetSingleProcIndex = function(Index: integer):Single of object;
  1791. TGetCurrencyProc = function : Currency of object;
  1792. TGetCurrencyProcIndex = function(Index: integer) : Currency of object;
  1793. var
  1794. AMethod : TMethod;
  1795. begin
  1796. Result:=0.0;
  1797. case PropInfo^.PropProcs and 3 of
  1798. ptField:
  1799. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  1800. ftSingle:
  1801. Result:=PSingle(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1802. ftDouble:
  1803. Result:=PDouble(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1804. ftExtended:
  1805. Result:=PExtended(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1806. ftcomp:
  1807. Result:=PComp(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1808. ftcurr:
  1809. Result:=PCurrency(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1810. end;
  1811. ptStatic,
  1812. ptVirtual:
  1813. begin
  1814. if (PropInfo^.PropProcs and 3)=ptStatic then
  1815. AMethod.Code:=PropInfo^.GetProc
  1816. else
  1817. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1818. AMethod.Data:=Instance;
  1819. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  1820. ftSingle:
  1821. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  1822. Result:=TGetSingleProc(AMethod)()
  1823. else
  1824. Result:=TGetSingleProcIndex(AMethod)(PropInfo^.Index);
  1825. ftDouble:
  1826. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  1827. Result:=TGetDoubleProc(AMethod)()
  1828. else
  1829. Result:=TGetDoubleProcIndex(AMethod)(PropInfo^.Index);
  1830. ftExtended:
  1831. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  1832. Result:=TGetExtendedProc(AMethod)()
  1833. else
  1834. Result:=TGetExtendedProcIndex(AMethod)(PropInfo^.Index);
  1835. ftCurr:
  1836. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  1837. Result:=TGetCurrencyProc(AMethod)()
  1838. else
  1839. Result:=TGetCurrencyProcIndex(AMethod)(PropInfo^.Index);
  1840. end;
  1841. end;
  1842. end;
  1843. end;
  1844. Procedure SetFloatProp(Instance : TObject;PropInfo : PPropInfo; Value : Extended);
  1845. type
  1846. TSetExtendedProc = procedure(const AValue: Extended) of object;
  1847. TSetExtendedProcIndex = procedure(Index: integer; AValue: Extended) of object;
  1848. TSetDoubleProc = procedure(const AValue: Double) of object;
  1849. TSetDoubleProcIndex = procedure(Index: integer; AValue: Double) of object;
  1850. TSetSingleProc = procedure(const AValue: Single) of object;
  1851. TSetSingleProcIndex = procedure(Index: integer; AValue: Single) of object;
  1852. TSetCurrencyProc = procedure(const AValue: Currency) of object;
  1853. TSetCurrencyProcIndex = procedure(Index: integer; AValue: Currency) of object;
  1854. Var
  1855. AMethod : TMethod;
  1856. begin
  1857. case (PropInfo^.PropProcs shr 2) and 3 of
  1858. ptfield:
  1859. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  1860. ftSingle:
  1861. PSingle(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1862. ftDouble:
  1863. PDouble(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1864. ftExtended:
  1865. PExtended(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1866. {$ifdef FPC_COMP_IS_INT64}
  1867. ftComp:
  1868. PComp(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=trunc(Value);
  1869. {$else FPC_COMP_IS_INT64}
  1870. ftComp:
  1871. PComp(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Comp(Value);
  1872. {$endif FPC_COMP_IS_INT64}
  1873. ftCurr:
  1874. PCurrency(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1875. end;
  1876. ptStatic,
  1877. ptVirtual:
  1878. begin
  1879. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1880. AMethod.Code:=PropInfo^.SetProc
  1881. else
  1882. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1883. AMethod.Data:=Instance;
  1884. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  1885. ftSingle:
  1886. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  1887. TSetSingleProc(AMethod)(Value)
  1888. else
  1889. TSetSingleProcIndex(AMethod)(PropInfo^.Index,Value);
  1890. ftDouble:
  1891. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  1892. TSetDoubleProc(AMethod)(Value)
  1893. else
  1894. TSetDoubleProcIndex(AMethod)(PropInfo^.Index,Value);
  1895. ftExtended:
  1896. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  1897. TSetExtendedProc(AMethod)(Value)
  1898. else
  1899. TSetExtendedProcIndex(AMethod)(PropInfo^.Index,Value);
  1900. ftCurr:
  1901. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  1902. TSetCurrencyProc(AMethod)(Value)
  1903. else
  1904. TSetCurrencyProcIndex(AMethod)(PropInfo^.Index,Value);
  1905. end;
  1906. end;
  1907. end;
  1908. end;
  1909. function GetFloatProp(Instance: TObject; const PropName: string): Extended;
  1910. begin
  1911. Result:=GetFloatProp(Instance,FindPropInfo(Instance,PropName))
  1912. end;
  1913. Procedure SetFloatProp(Instance: TObject; const PropName: string; Value: Extended);
  1914. begin
  1915. SetFloatProp(Instance,FindPropInfo(Instance,PropName),Value);
  1916. end;
  1917. {$endif}
  1918. { ---------------------------------------------------------------------
  1919. Method properties
  1920. ---------------------------------------------------------------------}
  1921. Function GetMethodProp(Instance : TObject;PropInfo : PPropInfo) : TMethod;
  1922. type
  1923. TGetMethodProcIndex=function(Index: Longint): TMethod of object;
  1924. TGetMethodProc=function(): TMethod of object;
  1925. var
  1926. value: PMethod;
  1927. AMethod : TMethod;
  1928. begin
  1929. Result.Code:=nil;
  1930. Result.Data:=nil;
  1931. case (PropInfo^.PropProcs) and 3 of
  1932. ptField:
  1933. begin
  1934. Value:=PMethod(Pointer(Instance)+PtrUInt(PropInfo^.GetProc));
  1935. if Value<>nil then
  1936. Result:=Value^;
  1937. end;
  1938. ptStatic,
  1939. ptVirtual:
  1940. begin
  1941. if (PropInfo^.PropProcs and 3)=ptStatic then
  1942. AMethod.Code:=PropInfo^.GetProc
  1943. else
  1944. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1945. AMethod.Data:=Instance;
  1946. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1947. Result:=TGetMethodProcIndex(AMethod)(PropInfo^.Index)
  1948. else
  1949. Result:=TGetMethodProc(AMethod)();
  1950. end;
  1951. end;
  1952. end;
  1953. Procedure SetMethodProp(Instance : TObject;PropInfo : PPropInfo; const Value : TMethod);
  1954. type
  1955. TSetMethodProcIndex=procedure(index:longint;p:TMethod) of object;
  1956. TSetMethodProc=procedure(p:TMethod) of object;
  1957. var
  1958. AMethod : TMethod;
  1959. begin
  1960. case (PropInfo^.PropProcs shr 2) and 3 of
  1961. ptField:
  1962. PMethod(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^ := Value;
  1963. ptStatic,
  1964. ptVirtual:
  1965. begin
  1966. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1967. AMethod.Code:=PropInfo^.SetProc
  1968. else
  1969. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1970. AMethod.Data:=Instance;
  1971. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1972. TSetMethodProcIndex(AMethod)(PropInfo^.Index,Value)
  1973. else
  1974. TSetMethodProc(AMethod)(Value);
  1975. end;
  1976. end;
  1977. end;
  1978. Function GetMethodProp(Instance: TObject; const PropName: string): TMethod;
  1979. begin
  1980. Result:=GetMethodProp(Instance,FindPropInfo(Instance,PropName));
  1981. end;
  1982. Procedure SetMethodProp(Instance: TObject; const PropName: string; const Value: TMethod);
  1983. begin
  1984. SetMethodProp(Instance,FindPropInfo(Instance,PropName),Value);
  1985. end;
  1986. { ---------------------------------------------------------------------
  1987. Variant properties
  1988. ---------------------------------------------------------------------}
  1989. Procedure CheckVariantEvent(P : CodePointer);
  1990. begin
  1991. If (P=Nil) then
  1992. Raise Exception.Create(SErrNoVariantSupport);
  1993. end;
  1994. Function GetVariantProp(Instance : TObject;PropInfo : PPropInfo): Variant;
  1995. begin
  1996. CheckVariantEvent(CodePointer(OnGetVariantProp));
  1997. Result:=OnGetVariantProp(Instance,PropInfo);
  1998. end;
  1999. Procedure SetVariantProp(Instance : TObject;PropInfo : PPropInfo; const Value: Variant);
  2000. begin
  2001. CheckVariantEvent(CodePointer(OnSetVariantProp));
  2002. OnSetVariantProp(Instance,PropInfo,Value);
  2003. end;
  2004. Function GetVariantProp(Instance: TObject; const PropName: string): Variant;
  2005. begin
  2006. Result:=GetVariantProp(Instance,FindPropInfo(Instance,PropName));
  2007. end;
  2008. Procedure SetVariantProp(Instance: TObject; const PropName: string; const Value: Variant);
  2009. begin
  2010. SetVariantprop(instance,FindpropInfo(Instance,PropName),Value);
  2011. end;
  2012. { ---------------------------------------------------------------------
  2013. All properties through variant.
  2014. ---------------------------------------------------------------------}
  2015. Function GetPropValue(Instance: TObject; const PropName: string): Variant;
  2016. begin
  2017. Result := GetPropValue(Instance,FindPropInfo(Instance, PropName));
  2018. end;
  2019. Function GetPropValue(Instance: TObject; const PropName: string; PreferStrings: Boolean): Variant;
  2020. begin
  2021. Result := GetPropValue(Instance,FindPropInfo(Instance, PropName),PreferStrings);
  2022. end;
  2023. Function GetPropValue(Instance: TObject; PropInfo: PPropInfo): Variant;
  2024. begin
  2025. Result := GetPropValue(Instance, PropInfo, True);
  2026. end;
  2027. Function GetPropValue(Instance: TObject; PropInfo: PPropInfo; PreferStrings: Boolean): Variant;
  2028. begin
  2029. CheckVariantEvent(CodePointer(OnGetPropValue));
  2030. Result:=OnGetPropValue(Instance,PropInfo,PreferStrings);
  2031. end;
  2032. Procedure SetPropValue(Instance: TObject; const PropName: string; const Value: Variant);
  2033. begin
  2034. SetPropValue(Instance, FindPropInfo(Instance, PropName), Value);
  2035. end;
  2036. Procedure SetPropValue(Instance: TObject; PropInfo: PPropInfo; const Value: Variant);
  2037. begin
  2038. CheckVariantEvent(CodePointer(OnSetPropValue));
  2039. OnSetPropValue(Instance,PropInfo,Value);
  2040. end;
  2041. { ---------------------------------------------------------------------
  2042. Easy access methods that appeared in Delphi 5
  2043. ---------------------------------------------------------------------}
  2044. Function IsPublishedProp(Instance: TObject; const PropName: string): Boolean;
  2045. begin
  2046. Result:=GetPropInfo(Instance,PropName)<>Nil;
  2047. end;
  2048. Function IsPublishedProp(AClass: TClass; const PropName: string): Boolean;
  2049. begin
  2050. Result:=GetPropInfo(AClass,PropName)<>Nil;
  2051. end;
  2052. Function PropIsType(Instance: TObject; const PropName: string; TypeKind: TTypeKind): Boolean;
  2053. begin
  2054. Result:=PropType(Instance,PropName)=TypeKind
  2055. end;
  2056. Function PropIsType(AClass: TClass; const PropName: string; TypeKind: TTypeKind): Boolean;
  2057. begin
  2058. Result:=PropType(AClass,PropName)=TypeKind
  2059. end;
  2060. Function PropType(Instance: TObject; const PropName: string): TTypeKind;
  2061. begin
  2062. Result:=FindPropInfo(Instance,PropName)^.PropType^.Kind;
  2063. end;
  2064. Function PropType(AClass: TClass; const PropName: string): TTypeKind;
  2065. begin
  2066. Result:=FindPropInfo(AClass,PropName)^.PropType^.Kind;
  2067. end;
  2068. Function IsStoredProp(Instance: TObject; const PropName: string): Boolean;
  2069. begin
  2070. Result:=IsStoredProp(instance,FindPropInfo(Instance,PropName));
  2071. end;
  2072. { TParameterLocation }
  2073. function TParameterLocation.GetReference: Boolean;
  2074. begin
  2075. Result := (LocType and $80) <> 0;
  2076. end;
  2077. function TParameterLocation.GetRegType: TRegisterType;
  2078. begin
  2079. Result := TRegisterType(LocType and $7F);
  2080. end;
  2081. function TParameterLocation.GetShiftVal: Int8;
  2082. begin
  2083. if GetReference then begin
  2084. if Offset < Low(Int8) then
  2085. Result := Low(Int8)
  2086. else if Offset > High(Int8) then
  2087. Result := High(Int8)
  2088. else
  2089. Result := Offset;
  2090. end else
  2091. Result := 0;
  2092. end;
  2093. { TParameterLocations }
  2094. function TParameterLocations.GetLocation(aIndex: Byte): PParameterLocation;
  2095. begin
  2096. if aIndex >= Count then
  2097. Result := Nil
  2098. else
  2099. Result := PParameterLocation(@Count + SizeOf(Count) + SizeOf(TParameterLocation) * aIndex);
  2100. end;
  2101. { TProcedureParam }
  2102. function TProcedureParam.GetParamType: PTypeInfo;
  2103. begin
  2104. Result := DerefTypeInfoPtr(ParamTypeRef);
  2105. end;
  2106. function TProcedureParam.GetFlags: Byte;
  2107. begin
  2108. Result := PByte(@ParamFlags)^;
  2109. end;
  2110. { TManagedField }
  2111. function TManagedField.GetTypeRef: PTypeInfo;
  2112. begin
  2113. Result := DerefTypeInfoPtr(TypeRefRef);
  2114. end;
  2115. { TArrayTypeData }
  2116. function TArrayTypeData.GetElType: PTypeInfo;
  2117. begin
  2118. Result := DerefTypeInfoPtr(ElTypeRef);
  2119. end;
  2120. function TArrayTypeData.GetDims(aIndex: Byte): PTypeInfo;
  2121. begin
  2122. Result := DerefTypeInfoPtr(DimsRef[aIndex]);
  2123. end;
  2124. { TProcedureSignature }
  2125. function TProcedureSignature.GetResultType: PTypeInfo;
  2126. begin
  2127. Result := DerefTypeInfoPtr(ResultTypeRef);
  2128. end;
  2129. function TProcedureSignature.GetParam(ParamIndex: Integer): PProcedureParam;
  2130. begin
  2131. if (ParamIndex<0)or(ParamIndex>=ParamCount) then
  2132. Exit(nil);
  2133. Result := PProcedureParam(PByte(@Flags) + SizeOf(Self));
  2134. while ParamIndex > 0 do
  2135. begin
  2136. Result := PProcedureParam(aligntoptr((PByte(@Result^.Name) + (Length(Result^.Name) + 1) * SizeOf(AnsiChar))));
  2137. dec(ParamIndex);
  2138. end;
  2139. end;
  2140. { TTypeData }
  2141. function TTypeData.GetBaseType: PTypeInfo;
  2142. begin
  2143. Result := DerefTypeInfoPtr(BaseTypeRef);
  2144. end;
  2145. function TTypeData.GetCompType: PTypeInfo;
  2146. begin
  2147. Result := DerefTypeInfoPtr(CompTypeRef);
  2148. end;
  2149. function TTypeData.GetParentInfo: PTypeInfo;
  2150. begin
  2151. Result := DerefTypeInfoPtr(ParentInfoRef);
  2152. end;
  2153. {$ifndef VER3_0}
  2154. function TTypeData.GetRecInitData: PRecInitData;
  2155. begin
  2156. Result := PRecInitData(aligntoptr(PTypeData(RecInitInfo+2+PByte(RecInitInfo+1)^)));
  2157. end;
  2158. {$endif}
  2159. function TTypeData.GetHelperParent: PTypeInfo;
  2160. begin
  2161. Result := DerefTypeInfoPtr(HelperParentRef);
  2162. end;
  2163. function TTypeData.GetExtendedInfo: PTypeInfo;
  2164. begin
  2165. Result := DerefTypeInfoPtr(ExtendedInfoRef);
  2166. end;
  2167. function TTypeData.GetIntfParent: PTypeInfo;
  2168. begin
  2169. Result := DerefTypeInfoPtr(IntfParentRef);
  2170. end;
  2171. function TTypeData.GetRawIntfParent: PTypeInfo;
  2172. begin
  2173. Result := DerefTypeInfoPtr(RawIntfParentRef);
  2174. end;
  2175. function TTypeData.GetIIDStr: ShortString;
  2176. begin
  2177. Result := PShortString(Pointer(@RawIntfUnit) + Length(RawIntfUnit) + 1)^;
  2178. end;
  2179. function TTypeData.GetElType: PTypeInfo;
  2180. begin
  2181. Result := DerefTypeInfoPtr(elTypeRef);
  2182. end;
  2183. function TTypeData.GetElType2: PTypeInfo;
  2184. begin
  2185. Result := DerefTypeInfoPtr(elType2Ref);
  2186. end;
  2187. function TTypeData.GetInstanceType: PTypeInfo;
  2188. begin
  2189. Result := DerefTypeInfoPtr(InstanceTypeRef);
  2190. end;
  2191. function TTypeData.GetRefType: PTypeInfo;
  2192. begin
  2193. Result := DerefTypeInfoPtr(RefTypeRef);
  2194. end;
  2195. { TPropInfo }
  2196. function TPropInfo.GetPropType: PTypeInfo;
  2197. begin
  2198. Result := DerefTypeInfoPtr(PropTypeRef);
  2199. end;
  2200. end.