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 var
3 I, Curr: Integer;
4 Control: TControl;
5 List: TList;
6 begin
7 if Sender is TControl then
8 begin
9 // sender is an control
10 Control := Sender as TControl;
11 // check for parent control, managing the z-order
12 if Control.Parent = nil then
13 // not available
14 Exit;
15 // get position of the sender
16 Curr := -1;
17 for I := 0 to Pred(Control.Parent.ControlCount) do
18 if Control.Parent.Controls[I] = Sender then
19 begin
20 Curr := I;
21 Break;
22 end;
23 if Curr < 0 then
24 // hm, position not found
25 Exit;
26 List := TList.Create;
27 try
28 if MoveUp then
29 begin
30 for I := Curr + 2 to Pred(Control.Parent.ControlCount) do
31 // get the other controls, to be moved, too
32 List.Add(Control.Parent.Controls[I]);
33 // bring sender to front
34 Control.BringToFront;
35 for I := 0 to Pred(List.Count) do
36 // move the remaining controls
37 TControl(List[I]).BringToFront;
38 end
39 else
40 begin
41 for I := 0 to Curr - 2 do
42 // get the other controls, to be moved, too
43 List.Add(Control.Parent.Controls[I]);
44 // send sender to back
45 Control.SendToBack;
46 for I := Pred(List.Count) downto 0 do
47 // move the remaining controls
48 TControl(List[I]).SendToBack;
49 end;
50 finally
51 List.Free;
52 end;
53 end;
54 end;
|