Author: Daniel Wischnewski
How to move a control just one position within the z-order of the parent.
Answer:
The default methods
Usually you can bring any control on a form to front or send it to the back using
the methods supplied with the TControl class.
AnyControl.BringToFront;
AnyControl.SendToBack;
However, often these methods will not suffice. If you want to move the control just
one position, there are no public methods to acompolish just this. In the private
section of the TControl-class you find the method SetZOrderPosition which you
cannot use. Looking at the source code, you'll notice, you cannot even cut-n-copy
that, as it is accessing some private variables/objects, which are not made public
either.
A simple solution
The solution, to work around this limitation, is to move the control either to the
top or the back and move the others, that should remain in front (or behind), too.
The following procedure will do just this.
The first parameter Sender takes the control to be moved. The second paramter
points the direction. True will bring it to front, False will move it to the back.
1 procedure ChangeControlZOrder(Sender: TObject; MoveUp: Boolean = True);
2 var3 I, Curr: Integer;
4 Control: TControl;
5 List: TList;
6 begin7 if Sender is TControl then8 begin9 // sender is an control10 Control := Sender as TControl;
11 // check for parent control, managing the z-order12 if Control.Parent = nilthen13 // not available14 Exit;
15 // get position of the sender16 Curr := -1;
17 for I := 0to Pred(Control.Parent.ControlCount) do18 if Control.Parent.Controls[I] = Sender then19 begin20 Curr := I;
21 Break;
22 end;
23 if Curr < 0then24 // hm, position not found25 Exit;
26 List := TList.Create;
27 try28 if MoveUp then29 begin30 for I := Curr + 2to Pred(Control.Parent.ControlCount) do31 // get the other controls, to be moved, too32 List.Add(Control.Parent.Controls[I]);
33 // bring sender to front34 Control.BringToFront;
35 for I := 0to Pred(List.Count) do36 // move the remaining controls37 TControl(List[I]).BringToFront;
38 end39 else40 begin41 for I := 0to Curr - 2do42 // get the other controls, to be moved, too43 List.Add(Control.Parent.Controls[I]);
44 // send sender to back45 Control.SendToBack;
46 for I := Pred(List.Count) downto0do47 // move the remaining controls48 TControl(List[I]).SendToBack;
49 end;
50 finally51 List.Free;
52 end;
53 end;
54 end;