typinfo.pp 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by Florian Klaempfl
  5. member of the Free Pascal development team
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. { This unit provides the same Functionality as the TypInfo Unit }
  13. { of Delphi }
  14. unit typinfo;
  15. interface
  16. {$MODE objfpc}
  17. uses SysUtils;
  18. // temporary types:
  19. type
  20. {$ifndef HASVARIANT}
  21. Variant = Pointer;
  22. {$endif}
  23. {$MINENUMSIZE 1 this saves a lot of memory }
  24. // if you change one of the following enumeration types
  25. // you have also to change the compiler in an appropriate way !
  26. TTypeKind = (tkUnknown,tkInteger,tkChar,tkEnumeration,
  27. tkFloat,tkSet,tkMethod,tkSString,tkLString,tkAString,
  28. tkWString,tkVariant,tkArray,tkRecord,tkInterface,
  29. tkClass,tkObject,tkWChar,tkBool,tkInt64,tkQWord,
  30. tkDynArray,tkInterfaceRaw);
  31. TTOrdType = (otSByte,otUByte,otSWord,otUWord,otSLong,otULong);
  32. TFloatType = (ftSingle,ftDouble,ftExtended,ftComp,ftCurr);
  33. TMethodKind = (mkProcedure,mkFunction,mkConstructor,mkDestructor,
  34. mkClassProcedure, mkClassFunction);
  35. TParamFlags = set of (pfVar,pfConst,pfArray,pfAddress,pfReference,pfOut);
  36. TIntfFlag = (ifHasGuid,ifDispInterface,ifDispatch);
  37. TIntfFlags = set of TIntfFlag;
  38. TIntfFlagsBase = set of TIntfFlag;
  39. {$MINENUMSIZE DEFAULT}
  40. const
  41. ptField = 0;
  42. ptStatic = 1;
  43. ptVirtual = 2;
  44. ptConst = 3;
  45. tkString = tkSString;
  46. type
  47. TTypeKinds = set of TTypeKind;
  48. {$PACKRECORDS 1}
  49. TTypeInfo = record
  50. Kind : TTypeKind;
  51. Name : ShortString;
  52. // here the type data follows as TTypeData record
  53. end;
  54. PTypeInfo = ^TTypeInfo;
  55. PPTypeInfo = ^PTypeInfo;
  56. PTypeData = ^TTypeData;
  57. TTypeData = packed record
  58. case TTypeKind of
  59. tkUnKnown,tkLString,tkWString,tkAString,tkVariant:
  60. ();
  61. tkInteger,tkChar,tkEnumeration,tkWChar:
  62. (OrdType : TTOrdType;
  63. case TTypeKind of
  64. tkInteger,tkChar,tkEnumeration,tkBool,tkWChar : (
  65. MinValue,MaxValue : Longint;
  66. case TTypeKind of
  67. tkEnumeration:
  68. (
  69. BaseType : PTypeInfo;
  70. NameList : ShortString)
  71. );
  72. tkSet:
  73. (CompType : PTypeInfo)
  74. );
  75. tkFloat:
  76. (FloatType : TFloatType);
  77. tkSString:
  78. (MaxLength : Byte);
  79. tkClass:
  80. (ClassType : TClass;
  81. ParentInfo : PTypeInfo;
  82. PropCount : SmallInt;
  83. UnitName : ShortString
  84. // here the properties follow as array of TPropInfo
  85. );
  86. tkMethod:
  87. (MethodKind : TMethodKind;
  88. ParamCount : Byte;
  89. ParamList : array[0..1023] of Char
  90. {in reality ParamList is a array[1..ParamCount] of:
  91. record
  92. Flags : TParamFlags;
  93. ParamName : ShortString;
  94. TypeName : ShortString;
  95. end;
  96. followed by
  97. ResultType : ShortString}
  98. );
  99. tkInt64:
  100. (MinInt64Value, MaxInt64Value: Int64);
  101. tkQWord:
  102. (MinQWordValue, MaxQWordValue: QWord);
  103. tkInterface,
  104. tkInterfaceRaw:
  105. (
  106. IntfParent: PPTypeInfo;
  107. IID: PGUID;
  108. IIDStr: ShortString;
  109. IntfUnit: ShortString;
  110. );
  111. end;
  112. // unsed, just for completeness
  113. TPropData = packed record
  114. PropCount : Word;
  115. PropList : record end;
  116. end;
  117. PPropInfo = ^TPropInfo;
  118. TPropInfo = packed record
  119. PropType : PTypeInfo;
  120. GetProc : Pointer;
  121. SetProc : Pointer;
  122. StoredProc : Pointer;
  123. Index : Integer;
  124. Default : Longint;
  125. NameIndex : SmallInt;
  126. // contains the type of the Get/Set/Storedproc, see also ptxxx
  127. // bit 0..1 GetProc
  128. // 2..3 SetProc
  129. // 4..5 StoredProc
  130. // 6 : true, constant index property
  131. PropProcs : Byte;
  132. Name : ShortString;
  133. end;
  134. TProcInfoProc = Procedure(PropInfo : PPropInfo) of object;
  135. PPropList = ^TPropList;
  136. TPropList = array[0..65535] of PPropInfo;
  137. const
  138. tkAny = [Low(TTypeKind)..High(TTypeKind)];
  139. tkMethods = [tkMethod];
  140. tkProperties = tkAny-tkMethods-[tkUnknown];
  141. // general property handling
  142. Function GetTypeData(TypeInfo : PTypeInfo) : PTypeData;
  143. Function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string) : PPropInfo;
  144. Function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string; AKinds : TTypeKinds) : PPropInfo;
  145. Function GetPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds) : PPropInfo;
  146. Function GetPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  147. Function GetPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds) : PPropInfo;
  148. Function GetPropInfo(AClass: TClass; const PropName: string): PPropInfo;
  149. Function FindPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  150. Function FindPropInfo(AClass:TClass;const PropName: string): PPropInfo;
  151. Procedure GetPropInfos(TypeInfo : PTypeInfo;PropList : PPropList);
  152. Function GetPropList(TypeInfo : PTypeInfo;TypeKinds : TTypeKinds; PropList : PPropList) : Integer;
  153. // Property information routines.
  154. Function IsStoredProp(Instance: TObject;PropInfo : PPropInfo) : Boolean;
  155. Function IsStoredProp(Instance: TObject; const PropName: string): Boolean;
  156. Function IsPublishedProp(Instance: TObject; const PropName: string): Boolean;
  157. Function IsPublishedProp(AClass: TClass; const PropName: string): Boolean;
  158. Function PropType(Instance: TObject; const PropName: string): TTypeKind;
  159. Function PropType(AClass: TClass; const PropName: string): TTypeKind;
  160. Function PropIsType(Instance: TObject; const PropName: string; TypeKind: TTypeKind): Boolean;
  161. Function PropIsType(AClass: TClass; const PropName: string; TypeKind: TTypeKind): Boolean;
  162. // subroutines to read/write properties
  163. Function GetOrdProp(Instance: TObject; PropInfo : PPropInfo) : Longint;
  164. Function GetOrdProp(Instance: TObject; const PropName: string): Longint;
  165. Procedure SetOrdProp(Instance: TObject; PropInfo : PPropInfo; Value : Longint);
  166. Procedure SetOrdProp(Instance: TObject; const PropName: string; Value: Longint);
  167. Function GetEnumProp(Instance: TObject; const PropName: string): string;
  168. Function GetEnumProp(Instance: TObject; const PropInfo: PPropInfo): string;
  169. Procedure SetEnumProp(Instance: TObject; const PropName: string;const Value: string);
  170. Procedure SetEnumProp(Instance: TObject; const PropInfo: PPropInfo;const Value: string);
  171. Function GetSetProp(Instance: TObject; const PropName: string): string;
  172. Function GetSetProp(Instance: TObject; const PropName: string; Brackets: Boolean): string;
  173. Function GetSetProp(Instance: TObject; const PropInfo: PPropInfo; Brackets: Boolean): string;
  174. Procedure SetSetProp(Instance: TObject; const PropName: string; const Value: string);
  175. Procedure SetSetProp(Instance: TObject; const PropInfo: PPropInfo; const Value: string);
  176. Function GetStrProp(Instance: TObject; PropInfo : PPropInfo) : Ansistring;
  177. Function GetStrProp(Instance: TObject; const PropName: string): string;
  178. Procedure SetStrProp(Instance: TObject; const PropName: string; const Value: AnsiString);
  179. Procedure SetStrProp(Instance: TObject; PropInfo : PPropInfo; const Value : Ansistring);
  180. Function GetFloatProp(Instance: TObject; PropInfo : PPropInfo) : Extended;
  181. Function GetFloatProp(Instance: TObject; const PropName: string): Extended;
  182. Procedure SetFloatProp(Instance: TObject; const PropName: string; Value: Extended);
  183. Procedure SetFloatProp(Instance: TObject; PropInfo : PPropInfo; Value : Extended);
  184. Function GetVariantProp(Instance: TObject; PropInfo : PPropInfo): Variant;
  185. Function GetVariantProp(Instance: TObject; const PropName: string): Variant;
  186. Procedure SetVariantProp(Instance: TObject; const PropName: string; const Value: Variant);
  187. Procedure SetVariantProp(Instance: TObject; PropInfo : PPropInfo; const Value: Variant);
  188. Function GetObjectProp(Instance: TObject; const PropName: string): TObject;
  189. Function GetObjectProp(Instance: TObject; const PropName: string; MinClass: TClass): TObject;
  190. Function GetObjectProp(Instance: TObject; PropInfo: PPropInfo): TObject;
  191. Function GetObjectProp(Instance: TObject; PropInfo: PPropInfo; MinClass: TClass): TObject;
  192. Procedure SetObjectProp(Instance: TObject; const PropName: string; Value: TObject);
  193. Procedure SetObjectProp(Instance: TObject; PropInfo: PPropInfo; Value: TObject);
  194. Function GetObjectPropClass(Instance: TObject; const PropName: string): TClass;
  195. Function GetMethodProp(Instance: TObject; PropInfo: PPropInfo) : TMethod;
  196. Function GetMethodProp(Instance: TObject; const PropName: string): TMethod;
  197. Procedure SetMethodProp(Instance: TObject; PropInfo: PPropInfo; const Value : TMethod);
  198. Procedure SetMethodProp(Instance: TObject; const PropName: string; const Value: TMethod);
  199. Function GetInt64Prop(Instance: TObject; PropInfo: PPropInfo): Int64;
  200. Function GetInt64Prop(Instance: TObject; const PropName: string): Int64;
  201. Procedure SetInt64Prop(Instance: TObject; PropInfo: PPropInfo; const Value: Int64);
  202. Procedure SetInt64Prop(Instance: TObject; const PropName: string; const Value: Int64);
  203. Function GetPropValue(Instance: TObject; const PropName: string): Variant;
  204. Function GetPropValue(Instance: TObject; const PropName: string; PreferStrings: Boolean): Variant;
  205. Procedure SetPropValue(Instance: TObject; const PropName: string; const Value: Variant);
  206. // Auxiliary routines, which may be useful
  207. Function GetEnumName(TypeInfo : PTypeInfo;Value : Integer) : string;
  208. Function GetEnumValue(TypeInfo : PTypeInfo;const Name : string) : Integer;
  209. function SetToString(PropInfo: PPropInfo; Value: Integer; Brackets: Boolean) : String;
  210. function SetToString(PropInfo: PPropInfo; Value: Integer) : String;
  211. function StringToSet(PropInfo: PPropInfo; const Value: string): Integer;
  212. const
  213. BooleanIdents: array[Boolean] of String = ('False', 'True');
  214. DotSep: String = '.';
  215. Type
  216. EPropertyError = Class(Exception);
  217. Implementation
  218. ResourceString
  219. SErrPropertyNotFound = 'Unknown property: "%s"';
  220. SErrUnknownEnumValue = 'Unknown enumeration value: "%s"';
  221. type
  222. PMethod = ^TMethod;
  223. { ---------------------------------------------------------------------
  224. Auxiliary methods
  225. ---------------------------------------------------------------------}
  226. Function GetEnumName(TypeInfo : PTypeInfo;Value : Integer) : string;
  227. Var PS : PShortString;
  228. PT : PTypeData;
  229. begin
  230. PT:=GetTypeData(TypeInfo);
  231. // ^.BaseType);
  232. // If PT^.MinValue<0 then Value:=Ord(Value<>0); {map to 0/1}
  233. PS:=@PT^.NameList;
  234. While Value>0 Do
  235. begin
  236. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  237. Dec(Value);
  238. end;
  239. Result:=PS^;
  240. end;
  241. Function GetEnumValue(TypeInfo : PTypeInfo;const Name : string) : Integer;
  242. Var PS : PShortString;
  243. PT : PTypeData;
  244. Count : longint;
  245. begin
  246. If Length(Name)=0 then
  247. exit(-1);
  248. PT:=GetTypeData(TypeInfo);
  249. Count:=0;
  250. Result:=-1;
  251. PS:=@PT^.NameList;
  252. While (Result=-1) and (PByte(PS)^<>0) do
  253. begin
  254. If CompareText(PS^, Name) = 0 then
  255. Result:=Count;
  256. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  257. Inc(Count);
  258. end;
  259. end;
  260. Function SetToString(PropInfo: PPropInfo; Value: Integer; Brackets: Boolean) : String;
  261. Var
  262. I : Integer;
  263. PTI : PTypeInfo;
  264. begin
  265. PTI:=GetTypeData(PropInfo^.PropType)^.CompType;
  266. Result:='';
  267. For I:=0 to SizeOf(Integer)*8-1 do
  268. begin
  269. if ((Value and 1)<>0) then
  270. begin
  271. If Result='' then
  272. Result:=GetEnumName(PTI,i)
  273. else
  274. Result:=Result+','+GetEnumName(PTI,I);
  275. end;
  276. Value:=Value shr 1;
  277. end;
  278. if Brackets then
  279. Result:='['+Result+']';
  280. end;
  281. Function SetToString(PropInfo: PPropInfo; Value: Integer) : String;
  282. begin
  283. Result:=SetToString(PropInfo,Value,False);
  284. end;
  285. Const
  286. SetDelim = ['[',']',',',' '];
  287. Function GetNextElement(Var S : String) : String;
  288. Var
  289. J : Integer;
  290. begin
  291. J:=1;
  292. Result:='';
  293. If Length(S)>0 then
  294. begin
  295. While (J<=Length(S)) and Not (S[j] in SetDelim) do
  296. Inc(j);
  297. Result:=Copy(S,1,j-1);
  298. Delete(S,1,j);
  299. end;
  300. end;
  301. Function StringToSet(PropInfo: PPropInfo; const Value: string): Integer;
  302. Var
  303. S,T : String;
  304. I : Integer;
  305. PTI : PTypeInfo;
  306. begin
  307. Result:=0;
  308. PTI:=GetTypeData(PropInfo^.PropType)^.Comptype;
  309. S:=Value;
  310. I:=1;
  311. If Length(S)>0 then
  312. begin
  313. While (I<=Length(S)) and (S[i] in SetDelim) do
  314. Inc(I);
  315. Delete(S,1,i-1);
  316. end;
  317. While (S<>'') do
  318. begin
  319. T:=GetNextElement(S);
  320. if T<>'' then
  321. begin
  322. I:=GetEnumValue(PTI,T);
  323. if (I<0) then
  324. raise EPropertyError.CreateFmt(SErrUnknownEnumValue, [T]);
  325. Result:=Result or (1 shl i);
  326. end;
  327. end;
  328. end;
  329. Function GetTypeData(TypeInfo : PTypeInfo) : PTypeData;
  330. begin
  331. GetTypeData:=PTypeData(pointer(TypeInfo)+2+PByte(pointer(TypeInfo)+1)^);
  332. end;
  333. { ---------------------------------------------------------------------
  334. Basic Type information functions.
  335. ---------------------------------------------------------------------}
  336. Function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string) : PPropInfo;
  337. var
  338. hp : PTypeData;
  339. i : longint;
  340. p : string;
  341. pd : ^TPropData;
  342. begin
  343. P:=UpCase(PropName);
  344. while Assigned(TypeInfo) do
  345. begin
  346. // skip the name
  347. hp:=GetTypeData(Typeinfo);
  348. // the class info rtti the property rtti follows immediatly
  349. pd:=pointer(pointer(@hp^.UnitName)+Length(hp^.UnitName)+1);
  350. Result:=@pd^.PropList;
  351. for i:=1 to pd^.PropCount do
  352. begin
  353. // found a property of that name ?
  354. if Upcase(Result^.Name)=P then
  355. exit;
  356. // skip to next property
  357. Result:=PPropInfo(pointer(@Result^.Name)+byte(Result^.Name[0])+1);
  358. end;
  359. // parent class
  360. Typeinfo:=hp^.ParentInfo;
  361. end;
  362. Result:=Nil;
  363. end;
  364. Function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string; Akinds : TTypeKinds) : PPropInfo;
  365. begin
  366. Result:=GetPropInfo(TypeInfo,PropName);
  367. If (Akinds<>[]) then
  368. If (Result<>Nil) then
  369. If Not (Result^.PropType^.Kind in AKinds) then
  370. Result:=Nil;
  371. end;
  372. Function GetPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds) : PPropInfo;
  373. begin
  374. Result:=GetPropInfo(PTypeInfo(AClass.ClassInfo),PropName,AKinds);
  375. end;
  376. Function GetPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds) : PPropInfo;
  377. begin
  378. Result:=GetPropInfo(Instance.ClassType,PropName,AKinds);
  379. end;
  380. Function GetPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  381. begin
  382. Result:=GetPropInfo(Instance,PropName,[]);
  383. end;
  384. Function GetPropInfo(AClass: TClass; const PropName: string): PPropInfo;
  385. begin
  386. Result:=GetPropInfo(AClass,PropName,[]);
  387. end;
  388. Function FindPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  389. begin
  390. result:=GetPropInfo(Instance, PropName);
  391. if Result=nil then
  392. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  393. end;
  394. Function FindPropInfo(AClass:TClass;const PropName: string): PPropInfo;
  395. begin
  396. result:=GetPropInfo(AClass,PropName);
  397. if result=nil then
  398. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  399. end;
  400. Function IsStoredProp(Instance : TObject;PropInfo : PPropInfo) : Boolean;
  401. type
  402. TBooleanFunc=function:boolean of object;
  403. var
  404. AMethod : TMethod;
  405. begin
  406. case (PropInfo^.PropProcs shr 4) and 3 of
  407. ptfield:
  408. Result:=PBoolean(Pointer(Instance)+Longint(PropInfo^.StoredProc))^;
  409. ptconst:
  410. Result:=LongBool(PropInfo^.StoredProc);
  411. ptstatic,
  412. ptvirtual:
  413. begin
  414. if (PropInfo^.PropProcs shr 4) and 3=ptstatic then
  415. AMethod.Code:=PropInfo^.StoredProc
  416. else
  417. AMethod.Code:=ppointer(Pointer(Instance.ClassType)+Longint(PropInfo^.StoredProc))^;
  418. AMethod.Data:=Instance;
  419. Result:=TBooleanFunc(AMethod)();
  420. end;
  421. end;
  422. end;
  423. Procedure GetPropInfos(TypeInfo : PTypeInfo;PropList : PPropList);
  424. {
  425. Store Pointers to property information in the list pointed
  426. to by proplist. PRopList must contain enough space to hold ALL
  427. properties.
  428. }
  429. Var
  430. TD : PTypeData;
  431. TP : PPropInfo;
  432. Count : Longint;
  433. begin
  434. TD:=GetTypeData(TypeInfo);
  435. // Get this objects TOTAL published properties count
  436. TP:=(@TD^.UnitName+Length(TD^.UnitName)+1);
  437. Count:=PWord(TP)^;
  438. // Now point TP to first propinfo record.
  439. Inc(Pointer(TP),SizeOF(Word));
  440. While Count>0 do
  441. begin
  442. PropList^[0]:=TP;
  443. Inc(Pointer(PropList),SizeOf(Pointer));
  444. // Point to TP next propinfo record.
  445. // Located at Name[Length(Name)+1] !
  446. TP:=PPropInfo(pointer(@TP^.Name)+PByte(@TP^.Name)^+1);
  447. Dec(Count);
  448. end;
  449. // recursive call for parent info.
  450. If TD^.Parentinfo<>Nil then
  451. GetPropInfos (TD^.ParentInfo,PropList);
  452. end;
  453. Procedure InsertProp (PL : PProplist;PI : PPropInfo; Count : longint);
  454. Var
  455. I : Longint;
  456. begin
  457. I:=0;
  458. While (I<Count) and (PI^.Name>PL^[I]^.Name) do
  459. Inc(I);
  460. If I<Count then
  461. Move(PL^[I], PL^[I+1], (Count - I) * SizeOf(Pointer));
  462. PL^[I]:=PI;
  463. end;
  464. Function GetPropList(TypeInfo : PTypeInfo;TypeKinds : TTypeKinds; PropList : PPropList) : Integer;
  465. {
  466. Store Pointers to property information OF A CERTAIN KIND in the list pointed
  467. to by proplist. PRopList must contain enough space to hold ALL
  468. properties.
  469. }
  470. Var
  471. TempList : PPropList;
  472. PropInfo : PPropinfo;
  473. I,Count : longint;
  474. begin
  475. Result:=0;
  476. Count:=GetTypeData(TypeInfo)^.Propcount;
  477. If Count>0 then
  478. begin
  479. GetMem(TempList,Count*SizeOf(Pointer));
  480. Try
  481. GetPropInfos(TypeInfo,TempList);
  482. For I:=0 to Count-1 do
  483. begin
  484. PropInfo:=TempList^[i];
  485. If PropInfo^.PropType^.Kind in TypeKinds then
  486. begin
  487. InsertProp(PropList,PropInfo,Result);
  488. Inc(Result);
  489. end;
  490. end;
  491. finally
  492. FreeMem(TempList,Count*SizeOf(Pointer));
  493. end;
  494. end;
  495. end;
  496. { ---------------------------------------------------------------------
  497. Property access functions
  498. ---------------------------------------------------------------------}
  499. { ---------------------------------------------------------------------
  500. Ordinal properties
  501. ---------------------------------------------------------------------}
  502. Function GetOrdProp(Instance : TObject;PropInfo : PPropInfo) : Longint;
  503. type
  504. TGetIntegerProcIndex=function(index:longint):longint of object;
  505. TGetIntegerProc=function:longint of object;
  506. var
  507. TypeInfo: PTypeInfo;
  508. AMethod : TMethod;
  509. begin
  510. Result:=0;
  511. case (PropInfo^.PropProcs) and 3 of
  512. ptfield:
  513. Result:=PLongint(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  514. ptstatic,
  515. ptvirtual :
  516. begin
  517. if (PropInfo^.PropProcs and 3)=ptStatic then
  518. AMethod.Code:=PropInfo^.GetProc
  519. else
  520. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^;
  521. AMethod.Data:=Instance;
  522. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  523. Result:=TGetIntegerProcIndex(AMethod)(PropInfo^.Index)
  524. else
  525. Result:=TGetIntegerProc(AMethod)();
  526. end;
  527. end;
  528. { cut off unnecessary stuff }
  529. TypeInfo := PropInfo^.PropType;
  530. case TypeInfo^.Kind of
  531. tkChar, tkBool:
  532. Result:=Result and $ff;
  533. tkWChar:
  534. Result:=Result and $ffff;
  535. tkEnumeration,
  536. tkInteger:
  537. case GetTypeData(TypeInfo)^.OrdType of
  538. otSWord,otUWord:
  539. Result:=Result and $ffff;
  540. otSByte,otUByte:
  541. Result:=Result and $ff;
  542. end;
  543. end;
  544. end;
  545. Procedure SetOrdProp(Instance : TObject;PropInfo : PPropInfo;Value : Longint);
  546. type
  547. TSetIntegerProcIndex=procedure(index,i:longint) of object;
  548. TSetIntegerProc=procedure(i:longint) of object;
  549. var
  550. DataSize: Integer;
  551. AMethod : TMethod;
  552. begin
  553. DataSize := 4;
  554. if PropInfo^.PropType^.Kind <> tkClass then
  555. begin
  556. { cut off unnecessary stuff }
  557. case GetTypeData(PropInfo^.PropType)^.OrdType of
  558. otSWord,otUWord:
  559. begin
  560. Value:=Value and $ffff;
  561. DataSize := 2;
  562. end;
  563. otSByte,otUByte:
  564. begin
  565. Value:=Value and $ff;
  566. DataSize := 1;
  567. end;
  568. end;
  569. end;
  570. case (PropInfo^.PropProcs shr 2) and 3 of
  571. ptfield:
  572. case DataSize of
  573. 1: PByte(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Byte(Value);
  574. 2: PWord(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Word(Value);
  575. 4: PLongint(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
  576. end;
  577. ptstatic,
  578. ptvirtual :
  579. begin
  580. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  581. AMethod.Code:=PropInfo^.SetProc
  582. else
  583. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.SetProc))^;
  584. AMethod.Data:=Instance;
  585. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  586. TSetIntegerProcIndex(AMethod)(PropInfo^.Index,Value)
  587. else
  588. TSetIntegerProc(AMethod)(Value);
  589. end;
  590. end;
  591. end;
  592. Function GetOrdProp(Instance: TObject; const PropName: string): Longint;
  593. begin
  594. Result:=GetOrdProp(Instance,FindPropInfo(Instance,PropName));
  595. end;
  596. Procedure SetOrdProp(Instance: TObject; const PropName: string; Value: Longint);
  597. begin
  598. SetOrdProp(Instance,FindPropInfo(Instance,PropName),Value);
  599. end;
  600. Function GetEnumProp(Instance: TObject; Const PropInfo: PPropInfo): string;
  601. begin
  602. Result:=GetEnumName(PropInfo^.PropType, GetOrdProp(Instance, PropInfo));
  603. end;
  604. Function GetEnumProp(Instance: TObject; const PropName: string): string;
  605. begin
  606. Result:=GetEnumProp(Instance,FindPropInfo(Instance,PropName));
  607. end;
  608. Procedure SetEnumProp(Instance: TObject; const PropName: string; const Value: string);
  609. begin
  610. SetEnumProp(Instance,FindPropInfo(Instance,PropName),Value);
  611. end;
  612. Procedure SetEnumProp(Instance: TObject; Const PropInfo : PPropInfo; const Value: string);
  613. Var
  614. PV : Longint;
  615. begin
  616. If PropInfo<>Nil then
  617. begin
  618. PV:=GetEnumValue(PropInfo^.PropType, Value);
  619. if (PV<0) then
  620. raise EPropertyError.CreateFmt(SErrUnknownEnumValue, [Value]);
  621. SetOrdProp(Instance, PropInfo,PV);
  622. end;
  623. end;
  624. { ---------------------------------------------------------------------
  625. Set properties
  626. ---------------------------------------------------------------------}
  627. Function GetSetProp(Instance: TObject; const PropName: string): string;
  628. begin
  629. Result:=GetSetProp(Instance,PropName,False);
  630. end;
  631. Function GetSetProp(Instance: TObject; const PropName: string; Brackets: Boolean): string;
  632. begin
  633. Result:=GetSetProp(Instance,FindPropInfo(Instance,PropName),Brackets);
  634. end;
  635. Function GetSetProp(Instance: TObject; const PropInfo: PPropInfo; Brackets: Boolean): string;
  636. begin
  637. Result:=SetToString(PropInfo,GetOrdProp(Instance,PropInfo),Brackets);
  638. end;
  639. Procedure SetSetProp(Instance: TObject; const PropName: string; const Value: string);
  640. begin
  641. SetSetProp(Instance,FindPropInfo(Instance,PropName),Value);
  642. end;
  643. Procedure SetSetProp(Instance: TObject; const PropInfo: PPropInfo; const Value: string);
  644. begin
  645. SetOrdProp(Instance,PropInfo,StringToSet(PropInfo,Value));
  646. end;
  647. { ---------------------------------------------------------------------
  648. Object properties
  649. ---------------------------------------------------------------------}
  650. Function GetObjectProp(Instance: TObject; const PropName: string): TObject;
  651. begin
  652. Result:=GetObjectProp(Instance,PropName,Nil);
  653. end;
  654. Function GetObjectProp(Instance: TObject; const PropName: string; MinClass: TClass): TObject;
  655. begin
  656. Result:=GetObjectProp(Instance,FindPropInfo(Instance,PropName),MinClass);
  657. end;
  658. Function GetObjectProp(Instance: TObject; PropInfo : PPropInfo): TObject;
  659. begin
  660. Result:=GetObjectProp(Instance,PropInfo,Nil);
  661. end;
  662. Function GetObjectProp(Instance: TObject; PropInfo : PPropInfo; MinClass: TClass): TObject;
  663. begin
  664. {$ifdef cpu64}
  665. Result:=TObject(GetInt64Prop(Instance,PropInfo));
  666. {$else cpu64}
  667. Result:=TObject(GetOrdProp(Instance,PropInfo));
  668. {$endif cpu64}
  669. If (MinClass<>Nil) and (Result<>Nil) Then
  670. If Not Result.InheritsFrom(MinClass) then
  671. Result:=Nil;
  672. end;
  673. Procedure SetObjectProp(Instance: TObject; const PropName: string; Value: TObject);
  674. begin
  675. SetObjectProp(Instance,FindPropInfo(Instance,PropName),Value);
  676. end;
  677. Procedure SetObjectProp(Instance: TObject; PropInfo : PPropInfo; Value: TObject);
  678. begin
  679. {$ifdef cpu64}
  680. SetInt64Prop(Instance,PropInfo,Int64(Value));
  681. {$else cpu64}
  682. SetOrdProp(Instance,PropInfo,Integer(Value));
  683. {$endif cpu64}
  684. end;
  685. Function GetObjectPropClass(Instance: TObject; const PropName: string): TClass;
  686. begin
  687. Result:=GetTypeData(FindPropInfo(Instance,PropName)^.PropType)^.ClassType;
  688. end;
  689. { ---------------------------------------------------------------------
  690. String properties
  691. ---------------------------------------------------------------------}
  692. Function GetStrProp(Instance: TObject; PropInfo: PPropInfo): AnsiString;
  693. type
  694. TGetShortStrProcIndex=function(index:longint):ShortString of object;
  695. TGetShortStrProc=function():ShortString of object;
  696. TGetAnsiStrProcIndex=function(index:longint):AnsiString of object;
  697. TGetAnsiStrProc=function():AnsiString of object;
  698. var
  699. AMethod : TMethod;
  700. begin
  701. Result:='';
  702. case Propinfo^.PropType^.Kind of
  703. tkSString:
  704. begin
  705. case (PropInfo^.PropProcs) and 3 of
  706. ptField:
  707. Result := PShortString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  708. ptstatic,
  709. ptvirtual :
  710. begin
  711. if (PropInfo^.PropProcs and 3)=ptStatic then
  712. AMethod.Code:=PropInfo^.GetProc
  713. else
  714. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^;
  715. AMethod.Data:=Instance;
  716. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  717. Result:=TGetShortStrProcIndex(AMethod)(PropInfo^.Index)
  718. else
  719. Result:=TGetShortStrProc(AMethod)();
  720. end;
  721. end;
  722. end;
  723. tkAString:
  724. begin
  725. case (PropInfo^.PropProcs) and 3 of
  726. ptField:
  727. Result := PAnsiString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  728. ptstatic,
  729. ptvirtual :
  730. begin
  731. if (PropInfo^.PropProcs and 3)=ptStatic then
  732. AMethod.Code:=PropInfo^.GetProc
  733. else
  734. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^;
  735. AMethod.Data:=Instance;
  736. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  737. Result:=TGetAnsiStrProcIndex(AMethod)(PropInfo^.Index)
  738. else
  739. Result:=TGetAnsiStrProc(AMethod)();
  740. end;
  741. end;
  742. end;
  743. end;
  744. end;
  745. Procedure SetStrProp(Instance : TObject;PropInfo : PPropInfo; const Value : AnsiString);
  746. type
  747. TSetShortStrProcIndex=procedure(index:longint;const s:ShortString) of object;
  748. TSetShortStrProc=procedure(const s:ShortString) of object;
  749. TSetAnsiStrProcIndex=procedure(index:longint;s:AnsiString) of object;
  750. TSetAnsiStrProc=procedure(s:AnsiString) of object;
  751. var
  752. AMethod : TMethod;
  753. begin
  754. case Propinfo^.PropType^.Kind of
  755. tkSString:
  756. begin
  757. case (PropInfo^.PropProcs shr 2) and 3 of
  758. ptField:
  759. PShortString(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  760. ptstatic,
  761. ptvirtual :
  762. begin
  763. if (PropInfo^.PropProcs and 3)=ptStatic then
  764. AMethod.Code:=PropInfo^.SetProc
  765. else
  766. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.SetProc))^;
  767. AMethod.Data:=Instance;
  768. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  769. TSetShortStrProcIndex(AMethod)(PropInfo^.Index,Value)
  770. else
  771. TSetShortStrProc(AMethod)(Value);
  772. end;
  773. end;
  774. end;
  775. tkAString:
  776. begin
  777. case (PropInfo^.PropProcs shr 2) and 3 of
  778. ptField:
  779. PAnsiString(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  780. ptstatic,
  781. ptvirtual :
  782. begin
  783. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  784. AMethod.Code:=PropInfo^.SetProc
  785. else
  786. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.SetProc))^;
  787. AMethod.Data:=Instance;
  788. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  789. TSetAnsiStrProcIndex(AMethod)(PropInfo^.Index,Value)
  790. else
  791. TSetAnsiStrProc(AMethod)(Value);
  792. end;
  793. end;
  794. end;
  795. end;
  796. end;
  797. Function GetStrProp(Instance: TObject; const PropName: string): string;
  798. begin
  799. Result:=GetStrProp(Instance,FindPropInfo(Instance,PropName));
  800. end;
  801. Procedure SetStrProp(Instance: TObject; const PropName: string; const Value: AnsiString);
  802. begin
  803. SetStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  804. end;
  805. { ---------------------------------------------------------------------
  806. Float properties
  807. ---------------------------------------------------------------------}
  808. function GetFloatProp(Instance : TObject;PropInfo : PPropInfo) : Extended;
  809. type
  810. TGetExtendedProc = function:Extended of object;
  811. TGetExtendedProcIndex = function(Index: integer): Extended of object;
  812. TGetDoubleProc = function:Double of object;
  813. TGetDoubleProcIndex = function(Index: integer): Double of object;
  814. TGetSingleProc = function:Single of object;
  815. TGetSingleProcIndex = function(Index: integer):Single of object;
  816. var
  817. AMethod : TMethod;
  818. begin
  819. Result:=0.0;
  820. case PropInfo^.PropProcs and 3 of
  821. ptField:
  822. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  823. ftSingle:
  824. Result:=PSingle(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  825. ftDouble:
  826. Result:=PDouble(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  827. ftExtended:
  828. Result:=PExtended(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  829. {$ifndef cpum68k}
  830. ftcomp:
  831. Result:=PComp(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  832. {$endif cpum68k}
  833. end;
  834. ptStatic,
  835. ptVirtual:
  836. begin
  837. if (PropInfo^.PropProcs and 3)=ptStatic then
  838. AMethod.Code:=PropInfo^.GetProc
  839. else
  840. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^;
  841. AMethod.Data:=Instance;
  842. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  843. ftSingle:
  844. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  845. Result:=TGetSingleProc(AMethod)()
  846. else
  847. Result:=TGetSingleProcIndex(AMethod)(PropInfo^.Index);
  848. ftDouble:
  849. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  850. Result:=TGetDoubleProc(AMethod)()
  851. else
  852. Result:=TGetDoubleProcIndex(AMethod)(PropInfo^.Index);
  853. ftExtended:
  854. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  855. Result:=TGetExtendedProc(AMethod)()
  856. else
  857. Result:=TGetExtendedProcIndex(AMethod)(PropInfo^.Index);
  858. end;
  859. end;
  860. end;
  861. end;
  862. Procedure SetFloatProp(Instance : TObject;PropInfo : PPropInfo; Value : Extended);
  863. type
  864. TSetExtendedProc = procedure(const AValue: Extended) of object;
  865. TSetExtendedProcIndex = procedure(Index: integer; const AValue: Extended) of object;
  866. TSetDoubleProc = procedure(const AValue: Double) of object;
  867. TSetDoubleProcIndex = procedure(Index: integer; const AValue: Double) of object;
  868. TSetSingleProc = procedure(const AValue: Single) of object;
  869. TSetSingleProcIndex = procedure(Index: integer; const AValue: Single) of object;
  870. Var
  871. AMethod : TMethod;
  872. begin
  873. case (PropInfo^.PropProcs shr 2) and 3 of
  874. ptfield:
  875. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  876. ftSingle:
  877. PSingle(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
  878. ftDouble:
  879. PDouble(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
  880. ftExtended:
  881. PExtended(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
  882. end;
  883. ptStatic,
  884. ptVirtual:
  885. begin
  886. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  887. AMethod.Code:=PropInfo^.SetProc
  888. else
  889. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.SetProc))^;
  890. AMethod.Data:=Instance;
  891. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  892. ftSingle:
  893. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  894. TSetSingleProc(AMethod)(Value)
  895. else
  896. TSetSingleProcIndex(AMethod)(PropInfo^.Index,Value);
  897. ftDouble:
  898. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  899. TSetDoubleProc(AMethod)(Value)
  900. else
  901. TSetDoubleProcIndex(AMethod)(PropInfo^.Index,Value);
  902. ftExtended:
  903. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  904. TSetExtendedProc(AMethod)(Value)
  905. else
  906. TSetExtendedProcIndex(AMethod)(PropInfo^.Index,Value);
  907. end;
  908. end;
  909. end;
  910. end;
  911. function GetFloatProp(Instance: TObject; const PropName: string): Extended;
  912. begin
  913. Result:=GetFloatProp(Instance,FindPropInfo(Instance,PropName))
  914. end;
  915. Procedure SetFloatProp(Instance: TObject; const PropName: string; Value: Extended);
  916. begin
  917. SetFloatProp(Instance,FindPropInfo(Instance,PropName),Value);
  918. end;
  919. { ---------------------------------------------------------------------
  920. Variant properties
  921. ---------------------------------------------------------------------}
  922. Function GetVariantProp(Instance : TObject;PropInfo : PPropInfo): Variant;
  923. begin
  924. {$warning GetVariantProp not implemented}
  925. {$ifdef HASVARIANT}
  926. Result:=Null;
  927. {$else}
  928. Result:=nil;
  929. {$endif}
  930. end;
  931. Procedure SetVariantProp(Instance : TObject;PropInfo : PPropInfo; const Value: Variant);
  932. begin
  933. {$warning SetVariantProp not implemented}
  934. end;
  935. Function GetVariantProp(Instance: TObject; const PropName: string): Variant;
  936. begin
  937. Result:=GetVariantProp(Instance,FindPropInfo(Instance,PropName));
  938. end;
  939. Procedure SetVariantProp(Instance: TObject; const PropName: string; const Value: Variant);
  940. begin
  941. SetVariantprop(instance,FindpropInfo(Instance,PropName),Value);
  942. end;
  943. { ---------------------------------------------------------------------
  944. Method properties
  945. ---------------------------------------------------------------------}
  946. Function GetMethodProp(Instance : TObject;PropInfo : PPropInfo) : TMethod;
  947. type
  948. TGetMethodProcIndex=function(index:longint):PMethod of object;
  949. TGetMethodProc=function():PMethod of object;
  950. var
  951. value: PMethod;
  952. AMethod : TMethod;
  953. begin
  954. Value:=nil;
  955. case (PropInfo^.PropProcs) and 3 of
  956. ptfield:
  957. Value:=PMethod(Pointer(Instance)+Longint(PropInfo^.GetProc));
  958. ptstatic,
  959. ptvirtual :
  960. begin
  961. if (PropInfo^.PropProcs and 3)=ptStatic then
  962. AMethod.Code:=PropInfo^.GetProc
  963. else
  964. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^;
  965. AMethod.Data:=Instance;
  966. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  967. Value:=TGetMethodProcIndex(AMethod)(PropInfo^.Index)
  968. else
  969. Value:=TGetMethodProc(AMethod)();
  970. end;
  971. end;
  972. if Value=nil then
  973. begin
  974. Result.Code:=nil;
  975. Result.Data:=nil;
  976. end
  977. else
  978. Result:=Value^;
  979. end;
  980. Procedure SetMethodProp(Instance : TObject;PropInfo : PPropInfo; const Value : TMethod);
  981. type
  982. TSetMethodProcIndex=procedure(index:longint;p:PMethod) of object;
  983. TSetMethodProc=procedure(p:PMethod) of object;
  984. var
  985. AMethod : TMethod;
  986. begin
  987. case (PropInfo^.PropProcs shr 2) and 3 of
  988. ptfield:
  989. PMethod(Pointer(Instance)+Longint(PropInfo^.SetProc))^ := Value;
  990. ptstatic,
  991. ptvirtual :
  992. begin
  993. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  994. AMethod.Code:=PropInfo^.SetProc
  995. else
  996. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.SetProc))^;
  997. AMethod.Data:=Instance;
  998. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  999. TSetMethodProcIndex(AMethod)(PropInfo^.Index,@Value)
  1000. else
  1001. TSetMethodProc(AMethod)(@Value);
  1002. end;
  1003. end;
  1004. end;
  1005. Function GetMethodProp(Instance: TObject; const PropName: string): TMethod;
  1006. begin
  1007. Result:=GetMethodProp(Instance,FindPropInfo(Instance,PropName));
  1008. end;
  1009. Procedure SetMethodProp(Instance: TObject; const PropName: string; const Value: TMethod);
  1010. begin
  1011. SetMethodProp(Instance,FindPropInfo(Instance,PropName),Value);
  1012. end;
  1013. { ---------------------------------------------------------------------
  1014. Int64 properties
  1015. ---------------------------------------------------------------------}
  1016. Function GetInt64Prop(Instance: TObject; PropInfo: PPropInfo): Int64;
  1017. type
  1018. TGetInt64ProcIndex=function(index:longint):Int64 of object;
  1019. TGetInt64Proc=function():Int64 of object;
  1020. var
  1021. AMethod : TMethod;
  1022. begin
  1023. Result:=0;
  1024. case (PropInfo^.PropProcs) and 3 of
  1025. ptfield:
  1026. Result:=PInt64(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  1027. ptstatic,
  1028. ptvirtual :
  1029. begin
  1030. if (PropInfo^.PropProcs and 3)=ptStatic then
  1031. AMethod.Code:=PropInfo^.GetProc
  1032. else
  1033. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^;
  1034. AMethod.Data:=Instance;
  1035. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1036. result:=TGetInt64ProcIndex(AMethod)(PropInfo^.Index)
  1037. else
  1038. result:=TGetInt64Proc(AMethod)();
  1039. end;
  1040. end;
  1041. end;
  1042. procedure SetInt64Prop(Instance: TObject; PropInfo: PPropInfo; const Value: Int64);
  1043. type
  1044. TSetInt64ProcIndex=procedure(index:longint;i:Int64) of object;
  1045. TSetInt64Proc=procedure(i:Int64) of object;
  1046. var
  1047. AMethod : TMethod;
  1048. begin
  1049. case (PropInfo^.PropProcs shr 2) and 3 of
  1050. ptfield:
  1051. PInt64(Pointer(Instance)+Longint(PropInfo^.SetProc))^ := Value;
  1052. ptstatic,
  1053. ptvirtual :
  1054. begin
  1055. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1056. AMethod.Code:=PropInfo^.SetProc
  1057. else
  1058. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.SetProc))^;
  1059. AMethod.Data:=Instance;
  1060. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1061. TSetInt64ProcIndex(AMethod)(PropInfo^.Index,Value)
  1062. else
  1063. TSetInt64Proc(AMethod)(Value);
  1064. end;
  1065. end;
  1066. end;
  1067. Function GetInt64Prop(Instance: TObject; const PropName: string): Int64;
  1068. begin
  1069. Result:=GetInt64Prop(Instance,FindPropInfo(Instance,PropName));
  1070. end;
  1071. Procedure SetInt64Prop(Instance: TObject; const PropName: string; const Value: Int64);
  1072. begin
  1073. SetInt64Prop(Instance,FindPropInfo(Instance,PropName),Value);
  1074. end;
  1075. { ---------------------------------------------------------------------
  1076. All properties through variant.
  1077. ---------------------------------------------------------------------}
  1078. Function GetPropValue(Instance: TObject; const PropName: string): Variant;
  1079. begin
  1080. Result:=GetPropValue(Instance,PropName,True);
  1081. end;
  1082. Function GetPropValue(Instance: TObject; const PropName: string; PreferStrings: Boolean): Variant;
  1083. begin
  1084. end;
  1085. Procedure SetPropValue(Instance: TObject; const PropName: string; const Value: Variant);
  1086. begin
  1087. end;
  1088. { ---------------------------------------------------------------------
  1089. Easy access methods that appeared in Delphi 5
  1090. ---------------------------------------------------------------------}
  1091. Function IsPublishedProp(Instance: TObject; const PropName: string): Boolean;
  1092. begin
  1093. Result:=GetPropInfo(Instance,PropName)<>Nil;
  1094. end;
  1095. Function IsPublishedProp(AClass: TClass; const PropName: string): Boolean;
  1096. begin
  1097. Result:=GetPropInfo(AClass,PropName)<>Nil;
  1098. end;
  1099. Function PropIsType(Instance: TObject; const PropName: string; TypeKind: TTypeKind): Boolean;
  1100. begin
  1101. Result:=FindPropInfo(Instance,PropName)^.PropType^.Kind=TypeKind
  1102. end;
  1103. Function PropIsType(AClass: TClass; const PropName: string; TypeKind: TTypeKind): Boolean;
  1104. begin
  1105. Result:=PropType(AClass,PropName)=TypeKind
  1106. end;
  1107. Function PropType(Instance: TObject; const PropName: string): TTypeKind;
  1108. begin
  1109. Result:=FindPropInfo(Instance,PropName)^.PropType^.Kind;
  1110. end;
  1111. Function PropType(AClass: TClass; const PropName: string): TTypeKind;
  1112. begin
  1113. Result:=FindPropInfo(AClass,PropName)^.PropType^.Kind;
  1114. end;
  1115. Function IsStoredProp(Instance: TObject; const PropName: string): Boolean;
  1116. begin
  1117. Result:=IsStoredProp(instance,FindPropInfo(Instance,PropName));
  1118. end;
  1119. end.
  1120. {
  1121. $Log$
  1122. Revision 1.23 2004-02-22 16:48:39 florian
  1123. * several 64 bit issues fixed
  1124. Revision 1.22 2004/02/21 22:53:49 florian
  1125. * several 64 bit/x86-64 fixes
  1126. Revision 1.21 2004/02/20 15:55:26 peter
  1127. * enable variant again
  1128. Revision 1.20 2003/12/24 22:27:13 peter
  1129. * removed assembler
  1130. * cleanup
  1131. Revision 1.19 2003/12/22 11:32:04 marco
  1132. * splitted up tintfflags into several components
  1133. Revision 1.18 2003/10/24 08:37:20 marco
  1134. * Fix from Peter
  1135. Revision 1.17 2003/10/17 20:58:27 olle
  1136. * Changed m68k to cpum68k, i386 to cpui386
  1137. Revision 1.16 2003/04/24 11:46:25 florian
  1138. * fixed wrong newlines
  1139. Revision 1.15 2003/03/29 16:55:56 michael
  1140. + Patch from Mattias Gaertner for single typeinfo
  1141. Revision 1.14 2002/09/07 16:01:22 peter
  1142. * old logs removed and tabs fixed
  1143. Revision 1.13 2002/04/04 18:32:59 peter
  1144. * merged getpropinfo fix
  1145. }