typinfo.pp 59 KB

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