PizzaProgram 9 Posted July 21, 2023 Probably this is a very basic question, but I simply can not find any working method... I'd like to change properties of many wincontrols, but only if necessary. Reason: I'm using special skinned components (AlphaSkin) and they call unnecessary repaint events. The trivial "solution" is to write code 2x: if myForm.Left <> calculateMySpecialValue(...) then myForm.Left := calculateMySpecialValue(...); But I'd like to have a universal procedure I can apply to everything! (TFont.Size, Grid1.Column.Width , etc.) I've tried this: procedure WR( i: PInteger; const new: integer ); begin if i^ <> new then i^ := new; end; But it does not compile with Delphi7 on many places. WR( @grid1.Columns[i].Width, trunc(grid1.Columns[i].Width * scale)-1); // ERROR: Variable required WR( PInteger(Addr(grid1.TitleFont.Size)), rFmv); // ERROR: Variable required Share this post Link to post
Remy Lebeau 1392 Posted July 21, 2023 You can't take a pointer to a property, like you are trying to do. You should look into using RTTI instead. Someone else was asking a similar question on StackOverflow just yesterday: https://stackoverflow.com/questions/76729720/how-do-i-get-a-pointer-to-a-property-in-delphi 1 Share this post Link to post
PizzaProgram 9 Posted July 21, 2023 OK, so it's not so simple, as I've hoped 😞 If I understand it right, I will need : GetPropValue() and SetPropValue() functions or rather: GetInt64Prop() ? interesting is I could not find any GetInt32Prop() nor GetIntProp() ... .. and I will need to call it somehow with : WR( o: object; const name: string; const v: integer ) WR( grid1.columns[i], 'Width', 66 ); right ? Share this post Link to post
KodeZwerg 54 Posted July 21, 2023 I can not answer if it is implemented in your Delphi 7 installation, maybe upgrade to a more common Delphi Community Edition can help. uses ...TypInfo, Rtti... function SetProperty(const AControl: TControl; const AProperty: string; const AValue: TValue): Boolean; var LControl: TControl; LRttiContext: TRttiContext; LRttiProperty: TRttiProperty; begin Result := False; try LControl := AControl; LRttiProperty := LRttiContext.GetType(LControl.ClassType).GetProperty(AProperty); if ((LRttiProperty <> nil) and (LRttiProperty.Visibility in [mvPrivate, mvProtected, mvPublic, mvPublished])) then begin LRttiProperty.SetValue(LControl, AValue); Result := True; end; except end; end; Call that method by giving a control as argument 1, write the property as it is named for argument 2 and finally as argument 3 put your wanted value in. Best of luck. Share this post Link to post
Remy Lebeau 1392 Posted July 22, 2023 2 hours ago, PizzaProgram said: If I understand it right, I will need : GetPropValue() and SetPropValue() functions I tend to stay away from those functions since they use Variant, which is usually unnecessary overhead. But it depends on your particular needs. 2 hours ago, PizzaProgram said: or rather: GetInt64Prop() ? interesting is I could not find any GetInt32Prop() nor GetIntProp() ... Integral properties are handled by GetOrdProp() and SetOrdProp() (as in, Ordinal) 1 Share this post Link to post
Remy Lebeau 1392 Posted July 22, 2023 (edited) 1 hour ago, KodeZwerg said: I can not answer if it is implemented in your Delphi 7 installation Extended RTTI via the System.Rtti unit was introduced in Delphi 2010. 1 hour ago, KodeZwerg said: if ((LRttiProperty <> nil) and (LRttiProperty.Visibility in [mvPrivate, mvProtected, mvPublic, mvPublished])) then Why filter by visibility rather than by writability? if (LRttiProperty <> nil) and LRttiProperty.IsWritable then Edited July 22, 2023 by Remy Lebeau Share this post Link to post
Brian Evans 105 Posted July 22, 2023 (edited) Could try overloads of a procedure. From the calling site it does what you want but requires a separate definition for each combination of argument types / number of arguments. Procedures and Functions - Overloading (Delphi) - RAD Studio (embarcadero.com) Added: Looks like not much use here due to not being able to easily get a reference to the property as a property vs as a value. Edited July 22, 2023 by Brian Evans Share this post Link to post