0

我正在进行一个包含许多子表单的项目。许多表格可能会同时打开。我想知道是否已经有一些东西可以用来管理和跟踪这些表单,就像 Windows 任务栏和/或任务管理器一样。如果不是,那么最好的方法是什么?如果这已经完成,我不想重新发明轮子。

描述

如上所述,这个项目有许多表格,可以一次打开。我还将实现一些可视化列表控件(很像任务栏或任务管理器)以供用户控制这些表单(或者在用户的情况下,这些表单称为窗口)。管理这些最理想的方法是首先在创建这些表单时捕获它们中的每一个,并将它们记录在某个地方。有些表单需要这种行为,有些表单不需要。例如,模态表单永远不需要这种处理。

我将授予用户显示、最小化或关闭这些表单的权限,以及其他一些未来未曾考虑过的处理,例如可能与这些表单之一关联的自定义弹出菜单(但这是另一个主题)。关键是,我需要构建一些东西来捕获这些表单并保持它们井然有序。

这还将包括一次与所有表单的其他一些用户交互,以及对每个表单的简单访问,类似于 Screen.Forms 已经工作的方式。例如,最小化所有表单 ( FormManager.MinimizeAll)、最大化当前活动表单 ( FormManager.ActiveForm.Maximize) 或使用特定表单 ( FormManager[3].Maximize) 的命令。

可能的选项

我知道有几种截然不同的方法可以实现相似的结果,并且还没有开始编码,因为每种方法都有不同的起点。选项是...

  • 从 Screen 中包装 Screen.Forms 和其他相关功能(这不会提供我想要的太多灵活性)
  • 每次我创建一个表单时,用这个表单管理器注册它(这很灵活,但我必须确保我总是注册每个创建的表单)
  • 构建一个主表单以向表单管理器注册其自身并从中继承所有内容(这也非常灵活,但方式不同,而且更复杂)

第二种选择听起来是迄今为止最有希望的。但同样,如果已经有解决方案,我不想开始构建它。我很自信我不是第一个这样做的人。我不知道如何搜索这样的东西,我在谷歌上没有得到任何与我想要的东西相关的东西。

4

3 回答 3

3

全局变量Screen(以单位为Forms单位)做了一些“跟踪”,即

于 2012-01-03T12:29:15.110 回答
3

您可以将每个表单添加到 TObjectList。我编写了一个名为 FormStack 的组件,它允许您添加表单(甚至是同名的表单)、检索、删除等。要获得类似任务管理器的行为,我认为您只需要迭代列表即可获取表单名字。希望您可以在这里使用一些东西来阐明您的想法。

这是 FormStack 的代码。

unit uFormstack;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Contnrs; 

type
  TFormstack = class(TComponent)
  private
    { Private declarations }
    FormList: TObjectList;
  protected
    { Protected declarations }
  public
    { Public declarations }
    Constructor Create(AOwner: TComponent); Override;
    Destructor Destroy; Override;
    Procedure Add(InstanceClass: TComponentClass; Var Reference);
    Procedure RemoveLast;
    Procedure RemoveAll;
    Function FindForm(AComponentClass: TComponentClass): Boolean; 
    Function GetForm(AComponentClass: TComponentClass): TObject;
    Function GetByIndex(AIndex: Integer): TObject;
    Procedure RemoveByIndex(AIndex: Integer);
  published
    { Published declarations }
  end;

procedure Register;

implementation

//{$R *.res}

procedure Register;
begin
  RegisterComponents('FormStack', [TFormstack]);
end;

{-----------------------------------------------------------------------------
  TFormStack
-----------------------------------------------------------------------------}

Constructor TFormStack.Create(AOwner: TComponent);
Begin
  Inherited Create(AOwner);
  FormList := TObjectList.Create;
  FormList.OwnsObjects := True;
End;

Destructor TFormStack.Destroy;
Begin
  FormList.Free;
  Inherited Destroy;
End;

Procedure TFormStack.Add(InstanceClass: TComponentClass; Var Reference);
Var
  Instance: TComponent;
Begin
  Instance := TComponent(InstanceClass.NewInstance);
  TComponent(Reference) := Instance;
  Instance.Create(Self); // Owner is FormList   <<-- blows up if datamodule in D2010
  FormList.Add(Instance);
  Instance.Tag := FormList.Count-1;
End;


Procedure TFormStack.RemoveAll;
Var
  I: Integer;
Begin
  For I := FormList.Count -1 downto 0 do  // last in first out
  begin
    Self.RemoveLast;
  End;
End;

// This removes the last form on the stack
Procedure TFormStack.RemoveLast;
Begin
  if FormList.Count > 0 then
     FormList.Remove(FormList.Items[FormList.Count-1]);
End;

Function TFormStack.FindForm(AComponentClass: TComponentClass): Boolean;
Var
  I: Integer;
Begin
  Result := False;
  For I := FormList.Count-1 downto 0 do
    If Formlist.Items[I].ClassType = AComponentClass then
      Result := True;
End;

Function TFormStack.GetForm(AComponentClass: TComponentClass): TObject;
Var
  I: Integer;
begin
  Result := Nil;
  For I := FormList.Count-1 downto 0 do
    If Formlist.Items[I].ClassType = AComponentClass then
      Result := FormList.Items[I];
end;

Function TFormStack.GetByIndex(AIndex: Integer): TObject;
begin
  Result := Nil;
  If FormList.Count-1 >= AIndex then
    Result := FormList.Items[AIndex];
end;

Procedure TFormStack.RemoveByIndex(AIndex: Integer);
begin
  If FormList.Count-1 >= AIndex then
    FormList.Remove(FormList.Items[AIndex]);
end;

end.
于 2012-01-03T14:01:55.400 回答
2

如果我对您的理解正确,您想在应用程序运行时在代码中跟踪它吗?也许你可以用 Screen.Forms 做点什么?

于 2012-01-03T12:26:51.383 回答