3

私は再びフレームを持ってここにいます。私はこのメインフォームを持っています:

ここに画像の説明を入力

フレームの使い方を理解するために作成された単純なフォームです。フォームの上部にある 2 つのボタンで、この 2 つのフレームを開きたいと思います。

フレーム1

ここに画像の説明を入力

と Frame2

ここに画像の説明を入力

最初のフレームの単純なコードは次のとおりです。

unit AppFrame1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  Vcl.StdCtrls;

type
  TFrame1 = class(TFrame)
    lblFrame1: TLabel;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

implementation

{$R *.dfm}

end.

2番目のフレームのコードは次のとおりです。

unit AppFrame2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  Vcl.StdCtrls;

type
  TFrame2 = class(TFrame)
    lblFrame2: TLabel;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

implementation

{$R *.dfm}

end.

したがって、2 つのフレームに特別なことは何もありません。メイン フォームからフレームを開くために、次のようなインターフェイスを作成しました。

unit FramesManager;

interface

uses
  Vcl.Forms, Vcl.StdCtrls, Vcl.ExtCtrls, Vcl.Controls;

type

  TFrameClass = class(TFrame)

  end;


  IFrameManager = interface
  ['{A00E0D1B-3438-4DC4-9794-702E8302B567}']
    procedure CreateGenericFrame(AParentPanel: TPanel; AFrameClass: TFrameClass);
    procedure DestroyGenericFrame();
  end;

  TFrameManager = class(TInterfacedObject, IFrameManager)
  private
    FGenericFrame: TFrameClass;
    procedure CreateGenericFrame(AParentPanel: TPanel; AFrameClass: TFrameClass);
    procedure DestroyGenericFrame();
  public
    property Frame: TFrameClass read FGenericFrame write FGenericFrame;
  end;

implementation

{ TFrameManagement }

procedure TFrameManager.CreateGenericFrame(AParentPanel: TPanel;
  AFrameClass: TFrameClass);
begin
  FGenericFrame := AFrameClass.Create(AParentPanel);
  FGenericFrame.Parent := AParentPanel;
  FGenericFrame.Align := alClient;
end;

procedure TFrameManager.DestroyGenericFrame;
begin
  FGenericFrame.Free;
end;

end.

この時点で、インターフェイスを使用して 2 つのフレームを作成するつもりですが、このタスクに到達する方法がわかりません。私のメインフォームコードはこれです:

unit Main;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  Vcl.ExtCtrls, FramesManager, Vcl.StdCtrls, AppFrame1, AppFrame2;

type
  TfrmMain = class(TForm)
    pnlCommands: TPanel;
    pnlFrames: TPanel;
    btnCrtFrame1: TButton;
    btnCrtFrame2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure btnCrtFrame1Click(Sender: TObject);
    procedure btnCrtFrame2Click(Sender: TObject);
  private
    FFrame: IFrameManager;
  public
    { Public declarations }
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.dfm}


procedure TfrmMain.FormCreate(Sender: TObject);
begin
  FFrame := TFrameManager.Create;
end;


procedure TfrmMain.btnCrtFrame1Click(Sender: TObject);
begin
  FFrame.CreateGenericFrame(pnlFrames, TFrame1);
end;

procedure TfrmMain.btnCrtFrame2Click(Sender: TObject);
begin
  FFrame.CreateGenericFrame(pnlFrames, TFrame2);
end;

end.

プロジェクトを共同コンパイルしようとすると、次のエラーが表示されます。

[dcc32 Error] Main.pas(41): E2010 Incompatible types: 'TFrameClass' and 'class of TFrame1'
[dcc32 Error] Main.pas(46): E2010 Incompatible types: 'TFrameClass' and 'class of TFrame2'

そこで、メインから2つのフレームを作成する方法を理解したいと思います。適切なオブジェクト タイプを TFrameClass に割り当てるにはどうすればよいですか? 私はジェネリックについて考えてきましたが、ユーザーがそれを開くことを選択したときにメインから作成できる「ジェネリック」フレームを開くために、この種のインターフェイスを実装する方法についてはわかりません。

私の問題を明確に説明できたことを願っていますが、理解するのが複雑に思えるかもしれません。

4

1 に答える 1

5
type
    TFrameClass = class(TFrame)
    end;

あなたのTFrameClass宣言は間違っています。現在、それは単なる別のクラスである TFrame の子孫として宣言されています。

必要なのはクラス参照です:

type
  TFrameClass = class of TFrame;

TFrame1と は両方ともからTFrame2派生しているため、両方を変数TFrameに入れることができます。TFrameClass

しかし、これは VCL のどこかにすでに存在していると確信してTFrameClassいます。その場合、この型を再宣言する必要はありません。

その後、FGenericFrameプライベート フィールドの型を のTFrame代わりにする必要がありTFrameClassます。

(また、これはジェネリックとは何の関係もありません。)

于 2016-09-28T09:33:52.323 に答える