如何实现某种表单管理器?

时间:2012-01-03 12:14:19

标签: delphi delphi-7 tform

我正处于一个包含许多子表单的项目中。许多表格可能会立即开放。我想知道是否已经可以用来管理和跟踪这些表单,就像windows任务栏和/或任务管理器一样。如果没有,那么最好的方法是什么?如果已经完成,我不想重新发明轮子。

描述

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

我将为用户提供显示,最小化或关闭这些表单的权限,以及其他一些未来的思考处理,例如可能是与这些表单之一相关联的自定义弹出菜单(但这是另一个主题)。关键是,我需要构建一些东西来捕获这些形式并保持它们的顺序。

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

可能的选项

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

  • 从屏幕中包装Screen.Forms和其他相关功能(这不会让我的灵活性太大)
  • 每次创建表单时,请使用此表单管理器进行注册(这非常灵活,但我必须确保始终注册每个创建的表单)
  • 构建一个主表单,用表单管理器注册自己的表单并从中继承所有内容(这也很灵活,但方式不同,而且复杂得多)

到目前为止,第二种选择听起来最有希望。但是,如果已经有了解决方案,我不想再开始构建它。我非常有信心我不是第一个这样做的人。我不知道如何搜索这样的东西,我对谷歌的想法没有任何意义。

3 个答案:

答案 0 :(得分:3)

全局变量Screen(在Forms单位中)执行一些"跟踪",即

答案 1 :(得分: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.

答案 2 :(得分:2)

如果我理解正确,您希望在应用运行时在代码中跟踪此内容吗? 也许你可以用Screen.Forms做点什么?