typinfo.pp 48 KB

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