typinfo.pp 48 KB

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