首页  编辑  

改变控件的Z-Order

Tags: /超级猛料/VCL/用户接口(界面)/   Date Created:

change the Z-order of you controls during runtime?

Author: Daniel Wischnewski  

{

 Sometimes you want to change the order of your controls during runtime.

 Usually you only can send them all the way to the front (Control.BringToFront) or

 send them all the way back (Control.SendToBack).

 The following procedure will help you moving a control just one position for or back.

 This is especially useful when using vector graphis or similar applications.

 The procedure takes the control to be moved as the first parameter.

 The direction is the second parameter (True brings the control one step up,

 False sends it one step back).

 Internally, this procedure works with SendToBack and BringToFront too, however,

 it creates an order list first and pushes the other controls as well.

}

procedure ChangeControlZOrder(Sender: TObject; MoveUp: Boolean = True);

var

 I, Curr: Integer;

 Control: TControl;

 List: TList;

begin

 if Sender is TControl then

 begin

   // only components of type TControl and descendends

   // work

   Control := Sender as TControl;

   // has no parent, cannot move ;-)

   if Control.Parent = nil then

     // quit

     Exit;

   // determine position in z-order

   Curr := -1;

   for I := 0 to Pred(Control.Parent.ControlCount) do

     if Control.Parent.Controls[I] = Sender then

     begin

       Curr := I;

       Break;

     end;

   if Curr < 0 then

     // position not found, quit

     Exit;

   List := TList.Create;

   try

     if MoveUp then

     begin

       for I := Curr + 2 to Pred(Control.Parent.ControlCount) do

         // load other controls in group

         List.Add(Control.Parent.Controls[I]);

       Control.BringToFront;

       for I := 0 to Pred(List.Count) do

         // move other controls to front, too

         TControl(List[I]).BringToFront;

     end else begin

       for I := 0 to Curr - 2 do

         // load other controls in group

         List.Add(Control.Parent.Controls[I]);

       Control.SendToBack;

       for I := Pred(List.Count) downto 0 do

         // move other controls to back, too

         TControl(List[I]).SendToBack;

     end;

   finally

     List.Free;

   end;

 end;

end;