#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    12
    Rep Power
    0

    Refering to multiple objects


    Hi,
    On a form in Delphi I have a load of objects (labels, edit boxes, shapes etc.) that I want to move. Basically I want to do:
    (all the objects).Left := (all the objects).Left + 100;
    I could do this individually, but I wondered if there was an easier way of doing this.
    I don't think I can use an array and iterate through since all the objects have different names because they are different types of object.

    I tried doing it like this:
    Code:
    procedure TForm1.Button1Click(Sender: TObject);
    var
    Test : TComponent;
    begin
      Test := label1 + Label2;
      TLabel(Test).left := TLabel(Test).left + 100;
    end;
    But a TComponent can only have one component assigned to it. So I don't know.

    Thanks in advance,

    Perran

    p.s. I don't want to move EVERY object on the form, so I can't just move all of them..
  2. #2
  3. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2013
    Location
    Saint-Petersburg, Russia
    Posts
    236
    Rep Power
    28
    Oops, wrong branch, sorry.
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2008
    Posts
    344
    Rep Power
    6
    Add TypeInfo (or System.TypeInfo depending on your Delphi Version) to your uses clause.

    Then add the following method to your form's object definition
    Code:
    TForm1 = class(TForm)
      ..
    private
      procedure MoveComponents(DeltaValue: Integer);//<--Add this to private section
      ..
    end;
    Add the code to your method:
    Code:
    procedure TForm1.MoveComponents(DeltaValue: Integer);
    var
       Temp: TComponent;
       PropInfo: PPropInfo;
       I: Integer;
       CurrentLeftPosition: Integer;
    begin
       for I := (ComponentCount - 1) downto 0 do
       begin
          Temp := Components[I];
          if Temp is TWinControl then
          begin
             PropInfo := GetPropInfo(Temp.ClassInfo, 'Left');
             if Assigned(PropInfo) then
             begin
                CurrentLeftPosition := (Temp as TWinControl).Left;
                SetOrdProp(Temp, PropInfo, CurrentLeftPosition + DeltaValue);
             end;
          end;
       end;
    end;
    And use like so:
    Code:
    procedure TForm1.BitBtn1Click(Sender: TObject);
    begin
       MoveComponents(100);
    end;
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    12
    Rep Power
    0
    Thanks for your reply majilumbo.
    I got the code working, and it moves all the edit boxes, buttons and stringgrids to the left.
    Do you know why it doesn't move any of the labels? And is there a way (I guess by using the component count) to move some of the buttons but not all of them?
    Thanks again,
    Perran
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2008
    Posts
    344
    Rep Power
    6
    Originally Posted by Perran
    Do you know why it doesn't move any of the labels?
    Sorry, I should have caught that, a TLabel is a TGraphicControl, not a TWinControl, that is why it doesn't move. See below for the change in code...
    Originally Posted by Perran
    is there a way (I guess by using the component count) to move some of the buttons but not all of them?
    Yes, here's the approach I took:
    each control on your form has a property called TAG. It is not used for anything (by design), so it gives the programmer a place holder for related data to your component. When a component is created, the Tag property has (by default) a value of 0 (zero). Simply change the tag property value of all those controls you don't want to move to some other value, (like 1).

    Here's the modified Code:
    Code:
    procedure TForm1.MoveComponents(DeltaValue: Integer);
    var
       Temp: TComponent;
       PropInfo: PPropInfo;
       I: Integer;
       CurrentLeftPosition: Integer;
    begin
      for I := (ComponentCount - 1) downto 0 do
      begin
        Temp := Components[I];
        PropInfo := GetPropInfo(Temp, 'Left');
        if Assigned(PropInfo) then
        begin
          if (Temp is TControl) then
          begin
            CurrentLeft := (Temp as TControl).Left;
            if (Temp as TControl).Tag = 0 then//move only if tag is 0
               SetOrdProp(Temp, PropInfo, CurrentLeft + DeltaValue);
          end;
        end;
      end;
    end;
    One more word, you may want to add code to ensure that the control stays visible on the form by making sure that the new "Left" value is not smaller than zero or the new left+width value isn't beyond the right side of the form.
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    12
    Rep Power
    0
    Ok great I'll try that out in a minute, thanks very much!
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2012
    Posts
    151
    Rep Power
    2
    Originally Posted by Perran
    Hi,
    On a form in Delphi I have a load of objects (labels, edit boxes, shapes etc.) that I want to move. Basically I want to do:
    (all the objects).Left := (all the objects).Left + 100;
    I could do this individually, but I wondered if there was an easier way of doing this.
    I don't think I can use an array and iterate through since all the objects have different names because they are different types of object.
    ...
    This is where you need to realize that all objects that you can see on the form (in runtime) are descendant of TControl class. And a form has Controls property that contains all controls in it. So for your case, you just query all members of this Controls property and adjust their Left property. Just do something like this:

    Code:
    procedure TForm2.AdjustAllMyControls;
    var
      vControl: TControl;
    begin
      for vControl in Self.Controls do
        vControl.Left := xxx;
    end;
    or if you are using older Delphi, you would do this:

    Code:
    procedure TForm2.AdjustAllMyControls;
    var
      i: Integer;
    begin
      for i := 0 to Self.ControlCount-1 do
        Self.Controls[i].Left := xxx;
    end;

IMN logo majestic logo threadwatch logo seochat tools logo