typinfo.pp 48 KB

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