Recent

Author Topic: Is there something like "MethodAddress()" but for Properties?  (Read 1909 times)

garlar27

  • Hero Member
  • *****
  • Posts: 652
Is there something like "MethodAddress()" but for Properties?
« on: September 12, 2018, 09:42:54 pm »
I need to set an object's property, this object is of an unknown Class. The only thing I know is the property name and type.

For instance:
    I need to set all form's components' "OnMOuseDown" event to my own "@OnFooMouseDownActions"

I thought that something like this would work but it doesn't because "AFld" is always nil:
Code: Pascal  [Select][+][-]
  1.    procedure SetAllChildsOnMouseDownEventTo(const ACtrl: TControl; const AnEvent: TMouseEvent);
  2.    var
  3.       ind: Integer;
  4.       AFld: Pointer;
  5.    begin
  6.       for ind := 0 to ACtrl.ComponentCount -1 do begin
  7.          AFld := ACtrl.FieldAddress('OnMouseDown');
  8.          if Assigned(AFld) then begin
  9.             TMouseEvent(AFld^) := AnEvent; //<--- THIS LINE IS NOT REACHED...
  10.          end;
  11.          if ACtrl.Components[ind].ComponentCount > 0 then begin
  12.             SetAllChildsOnMouseDownEventTo(ACtrl.Components[ind], AnEvent);
  13.          end;
  14.       end; //<--- for ind //
  15.    end;
  16.  


I've been looking at this code but it looks like I'm using it wrong...
Code: Pascal  [Select][+][-]
  1. Procedure TComponent.SetReference(Enable: Boolean);
  2.  
  3. var
  4.   Field: ^TComponent;
  5. begin
  6.   if Assigned(Owner) then
  7.   begin
  8.     Field := Owner.FieldAddress(Name);
  9.     if Assigned(Field) then
  10.       if Enable then
  11.         Field^ := Self
  12.       else
  13.         Field^ := nil;
  14.   end;
  15. end;
  16.  

Does anybody knows how to do it right?

jamie

  • Hero Member
  • *****
  • Posts: 7493
Re: Is there something like "MethodAddress()" but for Properties?
« Reply #1 on: September 12, 2018, 10:59:19 pm »
I don't know why you want to do this but, you didn't indicate if you want all  Mouse down messages
or just those that have been assigned already in code?

 Something tells me you want to hook the mouse input, this can be done easily if you are on
windows because they supply a API to do so. As for the other widgets I can't say but I do think you
should be able to do this in the Application object interface, where as you can insert a message hanlder
etc..
The only true wisdom is knowing you know nothing

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Is there something like "MethodAddress()" but for Properties?
« Reply #2 on: September 12, 2018, 11:06:12 pm »
something along the lines of
Code: Pascal  [Select][+][-]
  1.  
  2. uses typinfo, ....;
  3.  
  4. procedure TForm1.Test;
  5. begin
  6.   SetPropValue(Self,'OnMouseDown',@onMouseDown);
  7. end;
  8.  
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Is there something like "MethodAddress()" but for Properties?
« Reply #3 on: September 13, 2018, 12:13:12 am »
Having dropped a few controls on a form:

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Forms, Controls, StdCtrls, Classes;
  9.  
  10. type
  11.  
  12.   TForm1 = class(TForm)
  13.     Button1: TButton;
  14.     CheckBox1: TCheckBox;
  15.     Edit1: TEdit;
  16.     Label1: TLabel;
  17.     Memo1: TMemo;
  18.     procedure FormCreate(Sender: TObject);
  19.   private
  20.     procedure MouseDownEvent(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  21.     procedure SetAllChildrensOnMouseDownEventTo(const AWinCtrl: TWinControl; const AnEvent: TMouseEvent);
  22.   end;
  23.  
  24. var
  25.   Form1: TForm1;
  26.  
  27. implementation
  28.  
  29. uses TypInfo, SysUtils;
  30.  
  31. procedure TForm1.FormCreate(Sender: TObject);
  32. begin
  33.   SetAllChildrensOnMouseDownEventTo(Self, @MouseDownEvent);
  34.   Constraints.MinWidth := 400;
  35. end;
  36.  
  37. procedure TForm1.MouseDownEvent(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  38. begin
  39.   Caption := Format('MouseDownEvent for %s at (%d,%d)',[Sender.ClassName,X,Y]);
  40. end;
  41.  
  42. procedure TForm1.SetAllChildrensOnMouseDownEventTo(const AWinCtrl: TWinControl; const AnEvent: TMouseEvent);
  43. var
  44.   ctl: TControl;
  45.   i: Integer;
  46. begin
  47.   for i := 0 to AWinCtrl.ControlCount-1 do begin
  48.     ctl := AWinCtrl.Controls[i];
  49.     SetMethodProp(ctl, 'OnMouseDown', TMethod(@MouseDownEvent));
  50.   end;
  51. end;
  52.  
  53. {$R *.lfm}
  54.  
  55. end.

 

TinyPortal © 2005-2018