typinfo.pp 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554
  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) : Longint;
  180. Function GetOrdProp(Instance: TObject; const PropName: string): Longint;
  181. Procedure SetOrdProp(Instance: TObject; PropInfo : PPropInfo; Value : Longint);
  182. Procedure SetOrdProp(Instance: TObject; const PropName: string; Value: Longint);
  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) : Longint;
  563. type
  564. TGetIntegerProcIndex=function(index:longint):longint of object;
  565. TGetIntegerProc=function:longint of object;
  566. TGetWordProcIndex=function(index:longint):word of object;
  567. TGetWordProc=function:word of object;
  568. TGetByteProcIndex=function(index:longint):Byte of object;
  569. TGetByteProc=function:Byte of object;
  570. var
  571. TypeInfo: PTypeInfo;
  572. AMethod : TMethod;
  573. DataSize: Integer;
  574. OrdType: TOrdType;
  575. Signed: Boolean;
  576. begin
  577. Result:=0;
  578. TypeInfo := PropInfo^.PropType;
  579. Signed := false;
  580. DataSize := 4;
  581. case TypeInfo^.Kind of
  582. tkChar, tkBool:
  583. DataSize:=1;
  584. tkWChar:
  585. DataSize:=2;
  586. tkEnumeration,
  587. tkInteger:
  588. begin
  589. OrdType:=GetTypeData(TypeInfo)^.OrdType;
  590. case OrdType of
  591. otSByte,otUByte: DataSize := 1;
  592. otSWord,otUWord: DataSize := 2;
  593. end;
  594. Signed := OrdType in [otSByte,otSWord,otSLong];
  595. end;
  596. end;
  597. case (PropInfo^.PropProcs) and 3 of
  598. ptfield:
  599. if Signed then begin
  600. case DataSize of
  601. 1: Result:=PShortInt(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  602. 2: Result:=PSmallInt(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  603. 4: Result:=PLongint(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  604. end;
  605. end else begin
  606. case DataSize of
  607. 1: Result:=PByte(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  608. 2: Result:=PWord(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  609. 4: Result:=PLongint(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  610. end;
  611. end;
  612. ptstatic,
  613. ptvirtual :
  614. begin
  615. if (PropInfo^.PropProcs and 3)=ptStatic then
  616. AMethod.Code:=PropInfo^.GetProc
  617. else
  618. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^;
  619. AMethod.Data:=Instance;
  620. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then begin
  621. case DataSize of
  622. 1: Result:=TGetByteProcIndex(AMethod)(PropInfo^.Index);
  623. 2: Result:=TGetWordProcIndex(AMethod)(PropInfo^.Index);
  624. 4: Result:=TGetIntegerProcIndex(AMethod)(PropInfo^.Index);
  625. end;
  626. end else begin
  627. case DataSize of
  628. 1: Result:=TGetByteProc(AMethod)();
  629. 2: Result:=TGetWordProc(AMethod)();
  630. 4: Result:=TGetIntegerProc(AMethod)();
  631. end;
  632. end;
  633. if Signed then begin
  634. case DataSize of
  635. 1: Result:=ShortInt(Result);
  636. 2: Result:=SmallInt(Result);
  637. end;
  638. end;
  639. end;
  640. end;
  641. end;
  642. Procedure SetOrdProp(Instance : TObject;PropInfo : PPropInfo;Value : Longint);
  643. type
  644. TSetIntegerProcIndex=procedure(index,i:longint) of object;
  645. TSetIntegerProc=procedure(i:longint) of object;
  646. var
  647. DataSize: Integer;
  648. AMethod : TMethod;
  649. begin
  650. DataSize := 4;
  651. if PropInfo^.PropType^.Kind <> tkClass then
  652. begin
  653. { cut off unnecessary stuff }
  654. case GetTypeData(PropInfo^.PropType)^.OrdType of
  655. otSWord,otUWord:
  656. begin
  657. Value:=Value and $ffff;
  658. DataSize := 2;
  659. end;
  660. otSByte,otUByte:
  661. begin
  662. Value:=Value and $ff;
  663. DataSize := 1;
  664. end;
  665. end;
  666. end;
  667. case (PropInfo^.PropProcs shr 2) and 3 of
  668. ptfield:
  669. case DataSize of
  670. 1: PByte(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Byte(Value);
  671. 2: PWord(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Word(Value);
  672. 4: PLongint(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
  673. end;
  674. ptstatic,
  675. ptvirtual :
  676. begin
  677. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  678. AMethod.Code:=PropInfo^.SetProc
  679. else
  680. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.SetProc))^;
  681. AMethod.Data:=Instance;
  682. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  683. TSetIntegerProcIndex(AMethod)(PropInfo^.Index,Value)
  684. else
  685. TSetIntegerProc(AMethod)(Value);
  686. end;
  687. end;
  688. end;
  689. Function GetOrdProp(Instance: TObject; const PropName: string): Longint;
  690. begin
  691. Result:=GetOrdProp(Instance,FindPropInfo(Instance,PropName));
  692. end;
  693. Procedure SetOrdProp(Instance: TObject; const PropName: string; Value: Longint);
  694. begin
  695. SetOrdProp(Instance,FindPropInfo(Instance,PropName),Value);
  696. end;
  697. Function GetEnumProp(Instance: TObject; Const PropInfo: PPropInfo): string;
  698. begin
  699. Result:=GetEnumName(PropInfo^.PropType, GetOrdProp(Instance, PropInfo));
  700. end;
  701. Function GetEnumProp(Instance: TObject; const PropName: string): string;
  702. begin
  703. Result:=GetEnumProp(Instance,FindPropInfo(Instance,PropName));
  704. end;
  705. Procedure SetEnumProp(Instance: TObject; const PropName: string; const Value: string);
  706. begin
  707. SetEnumProp(Instance,FindPropInfo(Instance,PropName),Value);
  708. end;
  709. Procedure SetEnumProp(Instance: TObject; Const PropInfo : PPropInfo; const Value: string);
  710. Var
  711. PV : Longint;
  712. begin
  713. If PropInfo<>Nil then
  714. begin
  715. PV:=GetEnumValue(PropInfo^.PropType, Value);
  716. if (PV<0) then
  717. raise EPropertyError.CreateFmt(SErrUnknownEnumValue, [Value]);
  718. SetOrdProp(Instance, PropInfo,PV);
  719. end;
  720. end;
  721. { ---------------------------------------------------------------------
  722. Set properties
  723. ---------------------------------------------------------------------}
  724. Function GetSetProp(Instance: TObject; const PropName: string): string;
  725. begin
  726. Result:=GetSetProp(Instance,PropName,False);
  727. end;
  728. Function GetSetProp(Instance: TObject; const PropName: string; Brackets: Boolean): string;
  729. begin
  730. Result:=GetSetProp(Instance,FindPropInfo(Instance,PropName),Brackets);
  731. end;
  732. Function GetSetProp(Instance: TObject; const PropInfo: PPropInfo; Brackets: Boolean): string;
  733. begin
  734. Result:=SetToString(PropInfo,GetOrdProp(Instance,PropInfo),Brackets);
  735. end;
  736. Procedure SetSetProp(Instance: TObject; const PropName: string; const Value: string);
  737. begin
  738. SetSetProp(Instance,FindPropInfo(Instance,PropName),Value);
  739. end;
  740. Procedure SetSetProp(Instance: TObject; const PropInfo: PPropInfo; const Value: string);
  741. begin
  742. SetOrdProp(Instance,PropInfo,StringToSet(PropInfo,Value));
  743. end;
  744. { ---------------------------------------------------------------------
  745. Object properties
  746. ---------------------------------------------------------------------}
  747. Function GetObjectProp(Instance: TObject; const PropName: string): TObject;
  748. begin
  749. Result:=GetObjectProp(Instance,PropName,Nil);
  750. end;
  751. Function GetObjectProp(Instance: TObject; const PropName: string; MinClass: TClass): TObject;
  752. begin
  753. Result:=GetObjectProp(Instance,FindPropInfo(Instance,PropName),MinClass);
  754. end;
  755. Function GetObjectProp(Instance: TObject; PropInfo : PPropInfo): TObject;
  756. begin
  757. Result:=GetObjectProp(Instance,PropInfo,Nil);
  758. end;
  759. Function GetObjectProp(Instance: TObject; PropInfo : PPropInfo; MinClass: TClass): TObject;
  760. begin
  761. {$ifdef cpu64}
  762. Result:=TObject(GetInt64Prop(Instance,PropInfo));
  763. {$else cpu64}
  764. Result:=TObject(GetOrdProp(Instance,PropInfo));
  765. {$endif cpu64}
  766. If (MinClass<>Nil) and (Result<>Nil) Then
  767. If Not Result.InheritsFrom(MinClass) then
  768. Result:=Nil;
  769. end;
  770. Procedure SetObjectProp(Instance: TObject; const PropName: string; Value: TObject);
  771. begin
  772. SetObjectProp(Instance,FindPropInfo(Instance,PropName),Value);
  773. end;
  774. Procedure SetObjectProp(Instance: TObject; PropInfo : PPropInfo; Value: TObject);
  775. begin
  776. {$ifdef cpu64}
  777. SetInt64Prop(Instance,PropInfo,Int64(Value));
  778. {$else cpu64}
  779. SetOrdProp(Instance,PropInfo,Integer(Value));
  780. {$endif cpu64}
  781. end;
  782. Function GetObjectPropClass(Instance: TObject; const PropName: string): TClass;
  783. begin
  784. Result:=GetTypeData(FindPropInfo(Instance,PropName)^.PropType)^.ClassType;
  785. end;
  786. { ---------------------------------------------------------------------
  787. String properties
  788. ---------------------------------------------------------------------}
  789. Function GetStrProp(Instance: TObject; PropInfo: PPropInfo): AnsiString;
  790. type
  791. TGetShortStrProcIndex=function(index:longint):ShortString of object;
  792. TGetShortStrProc=function():ShortString of object;
  793. TGetAnsiStrProcIndex=function(index:longint):AnsiString of object;
  794. TGetAnsiStrProc=function():AnsiString of object;
  795. var
  796. AMethod : TMethod;
  797. begin
  798. Result:='';
  799. case Propinfo^.PropType^.Kind of
  800. {$ifdef HASWIDESTRING}
  801. tkWString:
  802. Result:=GetWideStrProp(Instance,PropInfo);
  803. {$endif HASWIDESTRING}
  804. tkSString:
  805. begin
  806. case (PropInfo^.PropProcs) and 3 of
  807. ptField:
  808. Result := PShortString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  809. ptstatic,
  810. ptvirtual :
  811. begin
  812. if (PropInfo^.PropProcs and 3)=ptStatic then
  813. AMethod.Code:=PropInfo^.GetProc
  814. else
  815. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^;
  816. AMethod.Data:=Instance;
  817. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  818. Result:=TGetShortStrProcIndex(AMethod)(PropInfo^.Index)
  819. else
  820. Result:=TGetShortStrProc(AMethod)();
  821. end;
  822. end;
  823. end;
  824. tkAString:
  825. begin
  826. case (PropInfo^.PropProcs) and 3 of
  827. ptField:
  828. Result := PAnsiString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  829. ptstatic,
  830. ptvirtual :
  831. begin
  832. if (PropInfo^.PropProcs and 3)=ptStatic then
  833. AMethod.Code:=PropInfo^.GetProc
  834. else
  835. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^;
  836. AMethod.Data:=Instance;
  837. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  838. Result:=TGetAnsiStrProcIndex(AMethod)(PropInfo^.Index)
  839. else
  840. Result:=TGetAnsiStrProc(AMethod)();
  841. end;
  842. end;
  843. end;
  844. end;
  845. end;
  846. Procedure SetStrProp(Instance : TObject;PropInfo : PPropInfo; const Value : AnsiString);
  847. type
  848. TSetShortStrProcIndex=procedure(index:longint;const s:ShortString) of object;
  849. TSetShortStrProc=procedure(const s:ShortString) of object;
  850. TSetAnsiStrProcIndex=procedure(index:longint;s:AnsiString) of object;
  851. TSetAnsiStrProc=procedure(s:AnsiString) of object;
  852. var
  853. AMethod : TMethod;
  854. begin
  855. case Propinfo^.PropType^.Kind of
  856. {$ifdef HASWIDESTRING}
  857. tkWString:
  858. SetWideStrProp(Instance,PropInfo,Value);
  859. {$endif HASWIDESTRING}
  860. tkSString:
  861. begin
  862. case (PropInfo^.PropProcs shr 2) and 3 of
  863. ptField:
  864. PShortString(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  865. ptstatic,
  866. ptvirtual :
  867. begin
  868. if (PropInfo^.PropProcs and 3)=ptStatic then
  869. AMethod.Code:=PropInfo^.SetProc
  870. else
  871. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.SetProc))^;
  872. AMethod.Data:=Instance;
  873. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  874. TSetShortStrProcIndex(AMethod)(PropInfo^.Index,Value)
  875. else
  876. TSetShortStrProc(AMethod)(Value);
  877. end;
  878. end;
  879. end;
  880. tkAString:
  881. begin
  882. case (PropInfo^.PropProcs shr 2) and 3 of
  883. ptField:
  884. PAnsiString(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  885. ptstatic,
  886. ptvirtual :
  887. begin
  888. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  889. AMethod.Code:=PropInfo^.SetProc
  890. else
  891. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.SetProc))^;
  892. AMethod.Data:=Instance;
  893. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  894. TSetAnsiStrProcIndex(AMethod)(PropInfo^.Index,Value)
  895. else
  896. TSetAnsiStrProc(AMethod)(Value);
  897. end;
  898. end;
  899. end;
  900. end;
  901. end;
  902. Function GetStrProp(Instance: TObject; const PropName: string): string;
  903. begin
  904. Result:=GetStrProp(Instance,FindPropInfo(Instance,PropName));
  905. end;
  906. Procedure SetStrProp(Instance: TObject; const PropName: string; const Value: AnsiString);
  907. begin
  908. SetStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  909. end;
  910. {$ifdef HASWIDESTRING}
  911. Function GetWideStrProp(Instance: TObject; const PropName: string): WideString;
  912. begin
  913. Result:=GetWideStrProp(Instance, FindPropInfo(Instance, PropName));
  914. end;
  915. procedure SetWideStrProp(Instance: TObject; const PropName: string; const Value: WideString);
  916. begin
  917. SetWideStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  918. end;
  919. Function GetWideStrProp(Instance: TObject; PropInfo: PPropInfo): WideString;
  920. type
  921. TGetWideStrProcIndex=function(index:longint):WideString of object;
  922. TGetWideStrProc=function():WideString of object;
  923. var
  924. AMethod : TMethod;
  925. begin
  926. Result:='';
  927. case Propinfo^.PropType^.Kind of
  928. tkSString,tkAString:
  929. Result:=GetStrProp(Instance,PropInfo);
  930. tkWString:
  931. begin
  932. case (PropInfo^.PropProcs) and 3 of
  933. ptField:
  934. Result := PWideString(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  935. ptstatic,
  936. ptvirtual :
  937. begin
  938. if (PropInfo^.PropProcs and 3)=ptStatic then
  939. AMethod.Code:=PropInfo^.GetProc
  940. else
  941. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  942. AMethod.Data:=Instance;
  943. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  944. Result:=TGetWideStrProcIndex(AMethod)(PropInfo^.Index)
  945. else
  946. Result:=TGetWideStrProc(AMethod)();
  947. end;
  948. end;
  949. end;
  950. end;
  951. end;
  952. Procedure SetWideStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: WideString);
  953. type
  954. TSetWideStrProcIndex=procedure(index:longint;s:WideString) of object;
  955. TSetWideStrProc=procedure(s:WideString) of object;
  956. var
  957. AMethod : TMethod;
  958. begin
  959. case Propinfo^.PropType^.Kind of
  960. tkSString,tkAString:
  961. SetStrProp(Instance,PropInfo,Value);
  962. tkWString:
  963. begin
  964. case (PropInfo^.PropProcs shr 2) and 3 of
  965. ptField:
  966. PWideString(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  967. ptstatic,
  968. ptvirtual :
  969. begin
  970. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  971. AMethod.Code:=PropInfo^.SetProc
  972. else
  973. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  974. AMethod.Data:=Instance;
  975. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  976. TSetWideStrProcIndex(AMethod)(PropInfo^.Index,Value)
  977. else
  978. TSetWideStrProc(AMethod)(Value);
  979. end;
  980. end;
  981. end;
  982. end;
  983. end;
  984. {$endif HASWIDESTRING}
  985. { ---------------------------------------------------------------------
  986. Float properties
  987. ---------------------------------------------------------------------}
  988. function GetFloatProp(Instance : TObject;PropInfo : PPropInfo) : Extended;
  989. type
  990. TGetExtendedProc = function:Extended of object;
  991. TGetExtendedProcIndex = function(Index: integer): Extended of object;
  992. TGetDoubleProc = function:Double of object;
  993. TGetDoubleProcIndex = function(Index: integer): Double of object;
  994. TGetSingleProc = function:Single of object;
  995. TGetSingleProcIndex = function(Index: integer):Single of object;
  996. {$ifdef HASCURRENCY}
  997. TGetCurrencyProc = function : Currency of object;
  998. TGetCurrencyProcIndex = function(Index: integer) : Currency of object;
  999. {$endif HASCURRENCY}
  1000. var
  1001. AMethod : TMethod;
  1002. begin
  1003. Result:=0.0;
  1004. case PropInfo^.PropProcs and 3 of
  1005. ptField:
  1006. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  1007. ftSingle:
  1008. Result:=PSingle(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  1009. ftDouble:
  1010. Result:=PDouble(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  1011. ftExtended:
  1012. Result:=PExtended(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  1013. ftcomp:
  1014. Result:=PComp(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  1015. {$ifdef HASCURRENCY}
  1016. ftcurr:
  1017. Result:=PCurrency(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  1018. {$endif HASCURRENCY}
  1019. end;
  1020. ptStatic,
  1021. ptVirtual:
  1022. begin
  1023. if (PropInfo^.PropProcs and 3)=ptStatic then
  1024. AMethod.Code:=PropInfo^.GetProc
  1025. else
  1026. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^;
  1027. AMethod.Data:=Instance;
  1028. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  1029. ftSingle:
  1030. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1031. Result:=TGetSingleProc(AMethod)()
  1032. else
  1033. Result:=TGetSingleProcIndex(AMethod)(PropInfo^.Index);
  1034. ftDouble:
  1035. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1036. Result:=TGetDoubleProc(AMethod)()
  1037. else
  1038. Result:=TGetDoubleProcIndex(AMethod)(PropInfo^.Index);
  1039. ftExtended:
  1040. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1041. Result:=TGetExtendedProc(AMethod)()
  1042. else
  1043. Result:=TGetExtendedProcIndex(AMethod)(PropInfo^.Index);
  1044. end;
  1045. end;
  1046. end;
  1047. end;
  1048. Procedure SetFloatProp(Instance : TObject;PropInfo : PPropInfo; Value : Extended);
  1049. type
  1050. TSetExtendedProc = procedure(const AValue: Extended) of object;
  1051. TSetExtendedProcIndex = procedure(Index: integer; const AValue: Extended) of object;
  1052. TSetDoubleProc = procedure(const AValue: Double) of object;
  1053. TSetDoubleProcIndex = procedure(Index: integer; const AValue: Double) of object;
  1054. TSetSingleProc = procedure(const AValue: Single) of object;
  1055. TSetSingleProcIndex = procedure(Index: integer; const AValue: Single) of object;
  1056. {$ifdef HASCURRENCY}
  1057. TSetCurrencyProc = procedure(const AValue: Currency) of object;
  1058. TSetCurrencyProcIndex = procedure(Index: integer; const AValue: Currency) of object;
  1059. {$endif HASCURRENCY}
  1060. Var
  1061. AMethod : TMethod;
  1062. begin
  1063. case (PropInfo^.PropProcs shr 2) and 3 of
  1064. ptfield:
  1065. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  1066. ftSingle:
  1067. PSingle(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
  1068. ftDouble:
  1069. PDouble(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
  1070. ftExtended:
  1071. PExtended(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
  1072. {$ifdef FPC_COMP_IS_INT64}
  1073. ftComp:
  1074. PComp(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=trunc(Value);
  1075. {$else FPC_COMP_IS_INT64}
  1076. ftComp:
  1077. PComp(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1078. {$endif FPC_COMP_IS_INT64}
  1079. end;
  1080. ptStatic,
  1081. ptVirtual:
  1082. begin
  1083. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1084. AMethod.Code:=PropInfo^.SetProc
  1085. else
  1086. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.SetProc))^;
  1087. AMethod.Data:=Instance;
  1088. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  1089. ftSingle:
  1090. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1091. TSetSingleProc(AMethod)(Value)
  1092. else
  1093. TSetSingleProcIndex(AMethod)(PropInfo^.Index,Value);
  1094. ftDouble:
  1095. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1096. TSetDoubleProc(AMethod)(Value)
  1097. else
  1098. TSetDoubleProcIndex(AMethod)(PropInfo^.Index,Value);
  1099. ftExtended:
  1100. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1101. TSetExtendedProc(AMethod)(Value)
  1102. else
  1103. TSetExtendedProcIndex(AMethod)(PropInfo^.Index,Value);
  1104. end;
  1105. end;
  1106. end;
  1107. end;
  1108. function GetFloatProp(Instance: TObject; const PropName: string): Extended;
  1109. begin
  1110. Result:=GetFloatProp(Instance,FindPropInfo(Instance,PropName))
  1111. end;
  1112. Procedure SetFloatProp(Instance: TObject; const PropName: string; Value: Extended);
  1113. begin
  1114. SetFloatProp(Instance,FindPropInfo(Instance,PropName),Value);
  1115. end;
  1116. { ---------------------------------------------------------------------
  1117. Variant properties
  1118. ---------------------------------------------------------------------}
  1119. Function GetVariantProp(Instance : TObject;PropInfo : PPropInfo): Variant;
  1120. begin
  1121. {$warning GetVariantProp not implemented}
  1122. {$ifdef HASVARIANT}
  1123. Result:=Null;
  1124. {$else}
  1125. Result:=nil;
  1126. {$endif}
  1127. end;
  1128. Procedure SetVariantProp(Instance : TObject;PropInfo : PPropInfo; const Value: Variant);
  1129. begin
  1130. {$warning SetVariantProp not implemented}
  1131. end;
  1132. Function GetVariantProp(Instance: TObject; const PropName: string): Variant;
  1133. begin
  1134. Result:=GetVariantProp(Instance,FindPropInfo(Instance,PropName));
  1135. end;
  1136. Procedure SetVariantProp(Instance: TObject; const PropName: string; const Value: Variant);
  1137. begin
  1138. SetVariantprop(instance,FindpropInfo(Instance,PropName),Value);
  1139. end;
  1140. { ---------------------------------------------------------------------
  1141. Method properties
  1142. ---------------------------------------------------------------------}
  1143. Function GetMethodProp(Instance : TObject;PropInfo : PPropInfo) : TMethod;
  1144. type
  1145. TGetMethodProcIndex=function(Index: Longint): TMethod of object;
  1146. TGetMethodProc=function(): TMethod of object;
  1147. var
  1148. value: PMethod;
  1149. AMethod : TMethod;
  1150. begin
  1151. Result.Code:=nil;
  1152. Result.Data:=nil;
  1153. case (PropInfo^.PropProcs) and 3 of
  1154. ptfield:
  1155. begin
  1156. Value:=PMethod(Pointer(Instance)+Longint(PropInfo^.GetProc));
  1157. if Value<>nil then
  1158. Result:=Value^;
  1159. end;
  1160. ptstatic,
  1161. ptvirtual :
  1162. begin
  1163. if (PropInfo^.PropProcs and 3)=ptStatic then
  1164. AMethod.Code:=PropInfo^.GetProc
  1165. else
  1166. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^;
  1167. AMethod.Data:=Instance;
  1168. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1169. Result:=TGetMethodProcIndex(AMethod)(PropInfo^.Index)
  1170. else
  1171. Result:=TGetMethodProc(AMethod)();
  1172. end;
  1173. end;
  1174. end;
  1175. Procedure SetMethodProp(Instance : TObject;PropInfo : PPropInfo; const Value : TMethod);
  1176. type
  1177. TSetMethodProcIndex=procedure(index:longint;p:PMethod) of object;
  1178. TSetMethodProc=procedure(p:PMethod) of object;
  1179. var
  1180. AMethod : TMethod;
  1181. begin
  1182. case (PropInfo^.PropProcs shr 2) and 3 of
  1183. ptfield:
  1184. PMethod(Pointer(Instance)+Longint(PropInfo^.SetProc))^ := Value;
  1185. ptstatic,
  1186. ptvirtual :
  1187. begin
  1188. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1189. AMethod.Code:=PropInfo^.SetProc
  1190. else
  1191. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.SetProc))^;
  1192. AMethod.Data:=Instance;
  1193. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1194. TSetMethodProcIndex(AMethod)(PropInfo^.Index,@Value)
  1195. else
  1196. TSetMethodProc(AMethod)(@Value);
  1197. end;
  1198. end;
  1199. end;
  1200. Function GetMethodProp(Instance: TObject; const PropName: string): TMethod;
  1201. begin
  1202. Result:=GetMethodProp(Instance,FindPropInfo(Instance,PropName));
  1203. end;
  1204. Procedure SetMethodProp(Instance: TObject; const PropName: string; const Value: TMethod);
  1205. begin
  1206. SetMethodProp(Instance,FindPropInfo(Instance,PropName),Value);
  1207. end;
  1208. { ---------------------------------------------------------------------
  1209. Int64 properties
  1210. ---------------------------------------------------------------------}
  1211. Function GetInt64Prop(Instance: TObject; PropInfo: PPropInfo): Int64;
  1212. type
  1213. TGetInt64ProcIndex=function(index:longint):Int64 of object;
  1214. TGetInt64Proc=function():Int64 of object;
  1215. var
  1216. AMethod : TMethod;
  1217. begin
  1218. Result:=0;
  1219. case (PropInfo^.PropProcs) and 3 of
  1220. ptfield:
  1221. Result:=PInt64(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  1222. ptstatic,
  1223. ptvirtual :
  1224. begin
  1225. if (PropInfo^.PropProcs and 3)=ptStatic then
  1226. AMethod.Code:=PropInfo^.GetProc
  1227. else
  1228. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^;
  1229. AMethod.Data:=Instance;
  1230. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1231. result:=TGetInt64ProcIndex(AMethod)(PropInfo^.Index)
  1232. else
  1233. result:=TGetInt64Proc(AMethod)();
  1234. end;
  1235. end;
  1236. end;
  1237. procedure SetInt64Prop(Instance: TObject; PropInfo: PPropInfo; const Value: Int64);
  1238. type
  1239. TSetInt64ProcIndex=procedure(index:longint;i:Int64) of object;
  1240. TSetInt64Proc=procedure(i:Int64) of object;
  1241. var
  1242. AMethod : TMethod;
  1243. begin
  1244. case (PropInfo^.PropProcs shr 2) and 3 of
  1245. ptfield:
  1246. PInt64(Pointer(Instance)+Longint(PropInfo^.SetProc))^ := Value;
  1247. ptstatic,
  1248. ptvirtual :
  1249. begin
  1250. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1251. AMethod.Code:=PropInfo^.SetProc
  1252. else
  1253. AMethod.Code:=PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.SetProc))^;
  1254. AMethod.Data:=Instance;
  1255. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1256. TSetInt64ProcIndex(AMethod)(PropInfo^.Index,Value)
  1257. else
  1258. TSetInt64Proc(AMethod)(Value);
  1259. end;
  1260. end;
  1261. end;
  1262. Function GetInt64Prop(Instance: TObject; const PropName: string): Int64;
  1263. begin
  1264. Result:=GetInt64Prop(Instance,FindPropInfo(Instance,PropName));
  1265. end;
  1266. Procedure SetInt64Prop(Instance: TObject; const PropName: string; const Value: Int64);
  1267. begin
  1268. SetInt64Prop(Instance,FindPropInfo(Instance,PropName),Value);
  1269. end;
  1270. { ---------------------------------------------------------------------
  1271. All properties through variant.
  1272. ---------------------------------------------------------------------}
  1273. Function GetPropValue(Instance: TObject; const PropName: string): Variant;
  1274. begin
  1275. Result:=GetPropValue(Instance,PropName,True);
  1276. end;
  1277. Function GetPropValue(Instance: TObject; const PropName: string; PreferStrings: Boolean): Variant;
  1278. begin
  1279. end;
  1280. Procedure SetPropValue(Instance: TObject; const PropName: string; const Value: Variant);
  1281. begin
  1282. end;
  1283. { ---------------------------------------------------------------------
  1284. Easy access methods that appeared in Delphi 5
  1285. ---------------------------------------------------------------------}
  1286. Function IsPublishedProp(Instance: TObject; const PropName: string): Boolean;
  1287. begin
  1288. Result:=GetPropInfo(Instance,PropName)<>Nil;
  1289. end;
  1290. Function IsPublishedProp(AClass: TClass; const PropName: string): Boolean;
  1291. begin
  1292. Result:=GetPropInfo(AClass,PropName)<>Nil;
  1293. end;
  1294. Function PropIsType(Instance: TObject; const PropName: string; TypeKind: TTypeKind): Boolean;
  1295. begin
  1296. Result:=FindPropInfo(Instance,PropName)^.PropType^.Kind=TypeKind
  1297. end;
  1298. Function PropIsType(AClass: TClass; const PropName: string; TypeKind: TTypeKind): Boolean;
  1299. begin
  1300. Result:=PropType(AClass,PropName)=TypeKind
  1301. end;
  1302. Function PropType(Instance: TObject; const PropName: string): TTypeKind;
  1303. begin
  1304. Result:=FindPropInfo(Instance,PropName)^.PropType^.Kind;
  1305. end;
  1306. Function PropType(AClass: TClass; const PropName: string): TTypeKind;
  1307. begin
  1308. Result:=FindPropInfo(AClass,PropName)^.PropType^.Kind;
  1309. end;
  1310. Function IsStoredProp(Instance: TObject; const PropName: string): Boolean;
  1311. begin
  1312. Result:=IsStoredProp(instance,FindPropInfo(Instance,PropName));
  1313. end;
  1314. end.
  1315. {
  1316. $Log$
  1317. Revision 1.39 2005-02-26 20:59:38 florian
  1318. * fixed 1.0.10 issue
  1319. Revision 1.38 2005/02/26 11:37:01 florian
  1320. + overload of GetPropList added
  1321. Revision 1.37 2005/02/22 12:14:56 marco
  1322. * getproplist sorted param added.
  1323. Revision 1.36 2005/02/14 17:13:31 peter
  1324. * truncate log
  1325. Revision 1.35 2005/02/08 16:10:29 florian
  1326. * TTOrdType -> TOrdType
  1327. }