1

我在 Delphi 中创建了 MDI 应用程序。让我们假设我的应用程序中有一堆在屏幕上可见的 MDIChild 表单。我想在这些表单上执行一个循环,并检查每个表单在屏幕上的显示顺序。

例如,如果我有 3 个 MDICHild 表格:

FormA, FormB,FormC

FormB部分重叠部分重叠FormAFormBFormC

我想将它们的 Z 属性(深度)标记如下:

FormB.Z = 2 // that form is between FormA and FormC
FormA.Z = 3 // that form's distance is longest from user, form is overlapped by FormB and 
FormC.Z = 1 // that form is at the top of all forms in my application 

谢谢你的时间。

4

2 回答 2

4

J的答案通过 Screen.Forms 循环。这包含应用程序中的所有表单,包括非 MDI 表单,正如我从您的评论中看到的那样。您可以手动过滤主表单和 About 框,但这很麻烦,您还需要对其他表单执行相同的操作。我真的不喜欢这样做,因为它似乎很容易出错。

您的问题说您只想知道父级中 MDI 子窗体的 z 顺序,在这种情况下,有一个更好的解决方案。

MDI 子项在 MDI 父窗体的 MDIChildren 属性中按 z 排序顺序列出。查找 Z 深度的代码如下所示(未经测试):

function FindChildDepth(Child : TForm) : Integer;
var
  i : Integer;
begin
  Result := -1; // Form not found
  for i := 0 to MDIChildCount-1 do
  begin
    if (MDIChildren[i] == Child) then
    begin
      Result := i;
      Exit;
    end;
  end;
end;

这应该返回 0 到 n-1 之间的子元素的深度,其中 0 是顶部,如果在 MDIChildren 数组中找不到表单,则返回 -1。如果您希望“1”表示顶部而不是 0,只需将 Result 设置为 i+1。

于 2009-11-11T01:05:18.270 回答
1

使用 Screen.Forms 属性遍历应用程序中的表单。它完全按照您的意愿按 Z 顺序返回它们。

例如,创建一个包含 1 个 MDIForm 和 3 个 MDIChild 表单的应用程序。

在主窗体的菜单选项中,输入:

procedure TForm1.mnuFormOrder2Click(Sender: TObject);
var
  i: Integer;
  s: String;
begin
  s := '';
  for i := 0 to Pred(Screen.FormCount) do
  begin
    s := s + Screen.Forms[i].Caption+#13;
  end;

  MessageBox(Self.Handle, PChar(s),
    PChar(Self.Caption), MB_OK or MB_ICONINFORMATION or MB_TASKMODAL);
end;

这将显示一条消息,其中列出了 Z 序列中的表格名称。它还将列出您的主要表单,但您可以将其编码出来。如果您将另一个子表单设为活动表单,然后再次单击菜单选项,您将看到表单的顺序已更改。

于 2009-11-10T15:03:56.357 回答