typinfo.pp 47 KB

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