Z Order of Controls in Delphi FireMonkey(Tom Yu的博客)

Get and set the Z Order of controls at runtime in Delphi FireMonkey.

This is a follow on to my earlier post where I provided a VCL solution.
Now Ive created a free FireMonkey unit that has the same get and set routines as the VCL solution.  The full source code is available for download

Source and Demo Project

Full source code provided.
Download here

The demo lets you get and set the Z Order of controls and also get a list of all controls in Z Order.

The list on the right hand side shows the Z order of all controls on the form.
You can change the Z order and watch the “B” TEdit move up and down through the Z Order.

What does Delphi Provide ?

Delphi provides a limited API to set 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;

But we need to reposition a control anywhere in the Z order !

Don’t panic – we can do that using code that I provide in this post.

How does my code work ?

The code uses a brute force approach, repeatedly bringing controls to the front until they are in the requested order.  It’s a primitive approach but it works well enough.

Get Z Order of a control

This is the code that you write. Pretty easy

var
  vZorder : integer;
begin
  vZorder:= zzGetControlZOrder (MyEdit);
end;

Modify the Z Order of a control

Another one liner.  The brute force happens behind the scenes

begin
 zzSetControlZOrder (MyEdit, 10);
end;

Reposition a control on top of another control

// reposition Edit1 to be on top of Edit2
begin
 zzSetControlZOrder (
          Edit1
         ,zzGetControlZOrder (Edit2) + 1
          );
end;

Reposition a control below another control

   // reposition Edit1 to be on top of Edit2
begin
 zzSetControlZOrder (
          Edit1
         ,zzGetControlZOrder (Edit2) - 1
          );
end;

FireMonkey dummy elements

Some FireMonkey objects such as TForm and TPanel always include a child # 0 that is used to paint the background or border.  Dont worry, I have coded around to ensure that these elements remain at the bottom of the list.

Close enough

In VCL – some controls such as TLabel are always positioned at the back and their Z Order can not be changed.

This is less of an issue for FireMoneky as TLabels can be brought to the front.  However, I expect it will still be an issue for some controls

With this in mind, the zzSetControlZOrder function will reorder the control to as close as possible to the Z position that 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 …

  • Tested for Delphi 10.1 Berlin and should work in many prior releases of Delphi
  • Supports FMX controls on Forms, Panels and Frames – and their descendents.
    Let me know if you are interested in others that dont work and Ill see what I can do.

What About VCL ?

This post is about FireMonkey.
See this post for my solution for VCL

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

Feedback

I’m interested in your feedback.  Let me know if you have an idea for improvement, find a bug or are interested in a scenario that the unit does not support.

Download

Download the demo project with full source code

https://scotthollows.com/2016/12/27/scott-hollows-z-order-of-controls-in-delphi-firemonkey-fmx/comment-page-1/#comment-41

时间: 2024-10-19 22:42:41

Z Order of Controls in Delphi FireMonkey(Tom Yu的博客)的相关文章

Getting Text Metrics in Firemonkey(delphiscience的博客)

Firemonkey’s abstract TCanvas class has been providing the dimensions of the bounding rectangle of some text on itself. On recent updates it has deprecated providing text rectangle directly in the canvas, in stead encouraged users to use TTextLayout

delphi 移动开发博客地址收集

这个是各位博主学习整理的笔记,很值得大家学习. XE2011的博客: http://www.cnblogs.com/xe2011/ 万一的博客:http://www.cnblogs.com/del/ 武稀松的博客:http://www.raysoftware.cn/ delphiteacher的博客:http://blog.csdn.net/DelphiTeacher 我一路走来的博客:http://blog.csdn.net/tingsking18/article/details/477210

Z Order(Copy From WIN32.HLP)

The Z order of a window indicates the window's position in a stack of overlapping windows. This window stack is oriented along an imaginary axis, the z-axis, extending outward from the screen. The window at the top of the Z order overlaps all other w

javascript - 浏览TOM大叔博客的学习笔记

part1 --------------------------------------------------------------------------------------------------------- 1. 前言 这两天看了一下TOM大叔的<深入理解js系列>中的基础部分,根据自己的实际情况,做了读书笔记,记录了部分容易绊脚的问题.写篇文章,供大家分享. 2. 关于HTMLCollection的"实时查询" var divs = document.ge

js便签笔记(12)——浏览TOM大叔博客的学习笔记 part2

1. 前言 昨天写了<js便签笔记(11)——浏览TOM大叔博客的学习笔记 part1>,简单记录了几个问题.part1的重点还是在于最后那个循环创建函数的问题,也就是多个子函数公用一个闭包数据的问题.如果觉得有兴趣,可以再重新翻出来看看. 今天继续把剩下的问题写完. 2. 作用域链 学js的人,即使初级入门的也都知道“原型链”,但是“作用域链”,可能好多人没有听说过.大部分人都知道或者听说过“闭包”,但是可能有好多人不知道闭包其实和作用域链有莫大的联系.如果理解闭包不从作用域链开始理解,那么

根据上篇博客联想到了C/C++和Delphi的内存分配和管理的问题

首先看上一篇博客关于类创建对象的问题:http://www.cnblogs.com/xumenger/p/4462975.html 联想到通过指针分配内存 我们通过指针动态分配了内存之后,需要记住这个指针(该指针指向分配的内存),比如C/C++中的 int *pi; pi =(int*) malloc(10* sizeof(int)); pi 就是用来记录分配的内存的地址.在Delphi中 var pi: PInteger; begin GetMem(p, sizeof(Integer)*10)

学习: Delphi FireMonkey 结构性初略分析

Delphi 下的FireMonkey,很好地实现了 DirectUI与跨平台.学习了解他,对DirectUI编程及项目的跨平台实现有一定帮助.虽然作为开发者个体,并不需要了解太多这些东西,只要求拿来能用能实现功能就行,但对 FireMonkey的学习分析,对自己程序设计思想的提升,会有一定帮助. 昨天用FireMonkey控件写了一个小例子,发现他的 Animation类在实现控件的小动画时,很高效,很灵活.初步印象是 FireMonkey的内核有很多值得学习的地方,尤其他的界面渲染上,可以深

Delphi Firemonkey在主线程 异步调用函数(延迟调用)

先看下面的FMX.Layouts.pas中一段代码 procedure TCustomScrollBox.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Single); begin FMouseEvents := True; inherited; if (Button = TMouseButton.mbLeft) then begin MousePosToAni(X, Y); AniMouseDown(ssTouch in S

TMsgThread, TCommThread -- 在delphi线程中实现消息循环(105篇博客,好多研究消息的文章)

在delphi线程中实现消息循环 在delphi线程中实现消息循环 Delphi的TThread类使用很方便,但是有时候我们需要在线程类中使用消息循环,delphi没有提供. 花了两天的事件研究了一下win32的消息系统,写了一个线程内消息循环的测试. 但是没有具体应用过,贴出来给有这方面需求的DFW参考一下.希望大家和我讨论. {----------------------------------------------------------------------------- Unit