typinfo.pp 74 KB

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