typinfo.pp 60 KB

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