5

メインの TForm でフレームを作成 (表示したいとき) および破棄 (非表示にしたいとき) する方法は? フレームの整列 = alClient.

私はこれを試しました:

フォーム:

unit main;

interface

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

type
  TFormMain = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    f1: TFrame1;
    f2: TFrame2;
  end;

var
  FormMain: TFormMain;

implementation

{$R *.dfm}

procedure TFormMain.FormCreate(Sender: TObject);
begin
  f1 := TFrame1.Create(Self);
  f1.Parent := Self;
end;

end.

最初のフレーム:

unit uFrame1;

interface

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

type
  TFrame1 = class(TFrame)
    btn1: TButton;
    procedure btn1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

implementation

{$R *.dfm}

uses main, uFrame2;

procedure TFrame1.btn1Click(Sender: TObject);
begin
  Self.Free;
  FormMain.f2 := TFrame2.Create(FormMain);
  FormMain.f2.Parent := FormMain;
end;

end.

2 番目のフレーム:

unit uFrame2;

interface

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

type
  TFrame2 = class(TFrame)
    lbl1: TLabel;
    btn1: TButton;
    procedure btn1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

implementation

{$R *.dfm}

uses main, uFrame1;

procedure TFrame2.btn1Click(Sender: TObject);
begin
  Self.Free;
  FormMain.f1 := TFrame1.Create(FormMain);
  FormMain.f1.Parent := FormMain;
end;

end.

しかし、FrameStart または Frame1 のボタンをクリックすると、アクセス ビアレーションでクラッシュします (TForm FormCreate は正常に動作します。つまり、FrameStart を作成して表示します)。

デルフィ 7。

最初のフレームで 2枠目で

4

2 に答える 2

9

Self.Freeこれらのイベント ハンドラーを呼び出すことはできません。イベント ハンドラーが戻ると、次に実行される VCL コードは、解放したばかりのオブジェクトへの参照を引き続き使用します。そして、それがアクセス違反の原因です。完全なデバッグ モードで FastMM を実行していた場合は、役立つ診断メッセージが表示されます。

これらのフレームは、より回りくどい方法で自滅する必要があります。CM_RELEASE メッセージをフレームに投稿して、フレームで呼び出すように依頼しますFree。メッセージを送信するのではなく投稿することで、処理中のすべてのメッセージが最初に処理されます。メッセージに応答するには、フレームにメッセージ ハンドラーを追加する必要があります。

于 2012-05-15T21:32:21.900 に答える
4

あなたはそれのいくつかを持っています。

この種のものの背後にある基本的な考え方。

フレームを保持するためにメインフォームにプライベート プロパティを追加します。

一度に1つだけが必要であると仮定して、ボタンクリックハンドラーで

if assigned(fMyFrame) then
begin
  fMyFrame.Free;
  fMyFrame := nil;
end;
fMyFrame := TSomeFrame.Create(self);
fMyFrame.Parent := self;
fMyFrame.blah...

買い替えるのではなく、手放したいとき

if assigned(fMyFrame) then
begin
  fMyFrame.Free;
  fMyFrame := nil;
end;

フレームで別のフレームを上げたい場合は、そこで上記を繰り返します。

フレームで発生させるフレームを兄弟にしたい場合、たとえば同じ親を持つ場合は、Form1 変数を使用しないでください。

fMyNextFrame.Parent = self.Parent;

これが機能するようになったら、これを改善できる方法はたくさんあります。これは、インターフェイスや継承の古典的なシナリオですが、最初にこれを少し理解してください。

mySomething := TMySomething.Create();

あなたは今、何かで何かをすることができます。あなたが無料で電話した後、それはできません、それはできません、そして何もさせません。

self.free をしないでください。ガソリンの樽でマッチで遊んでいるようなものです。痛いでしょう……。

于 2012-05-15T22:04:07.853 に答える