Z Order of Controls in Delphi VCL
Scott Hollows - 04/Dec/2016
Scott Hollows - 04/Dec/2016
[SHOWTOGROUPS=4,20]
Get and set the Z Order of controls at runtime in Delphi VCL.
If you are looking for a FireMonkey solution see this post
Delphi provides a limited API for the Z order of controls.
You can bring a control to the front or send it to the back … that is all.
There is no API to get and set the Z order of a control.
Don’t panic – we can fix that using code that I provide in this post.
Demo Project
Full source code provided. See download link https://www.dropbox.com/sh/5z85jv5sy14nj6c/AADpY10GE_FxsSErExvcotAua?dl=0.
The project demonstrated how to get and set the Z Order of controls.
You can change the Z order and watch the YELLOW TEdit move up and down through the Z Order.
The list on the right hand side shows the Z order of all controls on the form.
The Yellow TEdit that is being manipulated is highlighted in the list with “*******”
How does it work ?
The code uses the same BringToFront API repeatedly until everything is in the desired order. Its primitive but it works well enough.
It also deals with some other quirks, but the basic technique is based on brute force
Get Z Order of a control
This is the code that you write. Pretty easy
Modify the Z Order of a control
Another one liner. The brute force happens behind the scenes
Reposition a control on top of another control
Reposition a control below another control
Close enough
Some controls such as TLabel are always positioned at the back and their Z Order can not be changed. This can make it difficult for the zzSetControlZOrder function to reorder the control to exactly the right position, so it attempts to get it as close as possible to what you specify
Zero Based Z-Order
The Z Order is zero based, so the first control is # 0, the second control is #1.
Try to break it
You can throw any object that you like at the routines and they will survive. If you pass in something that does not have a Z-Order position, it wont do anything and it also wont crash, show an error or raise an error. The GET function will return -1. The SET function will return FALSE. I could have raised an error, but for the purposes that I built this it was more convenient to suppress all errors.
This works for …
This post is about VCL.
See this post for my solution for FireMonkey
There are minor differences between VCL and FireMonkey
1) FireMonkey creates a child TRectangle as element #0, placed at the bottom of the Z order in Forms and Panels.
2) You can not change the Z-Order for TLabel in VCL, but you can in FireMonkey
[/SHOWTOGROUPS]
Get and set the Z Order of controls at runtime in Delphi VCL.

If you are looking for a FireMonkey solution see this post
Delphi provides a limited API for the Z order of controls.
You can bring a control to the front or send it to the back … that is all.
Код:
begin
Edit1.BringToFront;
Edit2.SendToBack;
end;
Don’t panic – we can fix that using code that I provide in this post.
Demo Project

Full source code provided. See download link https://www.dropbox.com/sh/5z85jv5sy14nj6c/AADpY10GE_FxsSErExvcotAua?dl=0.
The project demonstrated how to get and set the Z Order of controls.
You can change the Z order and watch the YELLOW TEdit move up and down through the Z Order.
The list on the right hand side shows the Z order of all controls on the form.
The Yellow TEdit that is being manipulated is highlighted in the list with “*******”
How does it work ?
The code uses the same BringToFront API repeatedly until everything is in the desired order. Its primitive but it works well enough.
It also deals with some other quirks, but the basic technique is based on brute force
Get Z Order of a control
This is the code that you write. Pretty easy
Код:
var
vZorder : integer;
begin
vZorder:= zzGetControlZOrder (MyEdit);
end;
Another one liner. The brute force happens behind the scenes
Код:
begin
zzSetControlZOrder (MyEdit, 10);
end;
Код:
// reposition Edit1 to be on top of Edit2
begin
zzSetControlZOrder (
Edit1
,zzGetControlZOrder (Edit2) + 1
);
end;
Код:
// reposition Edit1 to be on top of Edit2
begin
zzSetControlZOrder (
Edit1
,zzGetControlZOrder (Edit2) - 1
);
end;
Some controls such as TLabel are always positioned at the back and their Z Order can not be changed. This can make it difficult for the zzSetControlZOrder function to reorder the control to exactly the right position, so it attempts to get it as close as possible to what you specify
Zero Based Z-Order
The Z Order is zero based, so the first control is # 0, the second control is #1.
Try to break it
You can throw any object that you like at the routines and they will survive. If you pass in something that does not have a Z-Order position, it wont do anything and it also wont crash, show an error or raise an error. The GET function will return -1. The SET function will return FALSE. I could have raised an error, but for the purposes that I built this it was more convenient to suppress all errors.
This works for …
- Controls on Forms, Panels and Frames.
- Tested for VCL in Delphi 10.1 Berlin and should work in many prior releases of Delphi
This post is about VCL.
See this post for my solution for FireMonkey
There are minor differences between VCL and FireMonkey
1) FireMonkey creates a child TRectangle as element #0, placed at the bottom of the Z order in Forms and Panels.
2) You can not change the Z-Order for TLabel in VCL, but you can in FireMonkey
[/SHOWTOGROUPS]