2

この質問を入力すると、おそらくそうすべきだとわかりました。

フォームを TPageControl にドッキングすると、form.Create() が呼び出されたときと form.ManualDock(pagecontrol,pagecontrol.alClient) が呼び出されたときに FormShow が呼び出されます。

フォームのドッキング解除も show を呼び出します。これは、ドッキング/ドッキング解除時にフォームが実際に「リセット」されるためだと思いますか?

これが設計どおりである場合は、そこで起動したくないコードを onCreate にリファクタリングします (設計が悪い場合を除きます)。

4

1 に答える 1

2

すべきかどうかは、技術的な質問よりも哲学的な質問です。イベントは、関数でも使用されるTForm.OnShow制御メッセージを実行することによって発生します。内部的に、このメッセージはイベント自体を起動するものを呼び出します。CM_DOCKCLIENTManualDockCM_SHOWINGCHANGED

次の例では、Form1 (ページ コントロールとボタンを含む) と Form2 (空でドッキング可能) の 2 つのフォームを使用します。どちらも自動作成されていると思います。

次のコードは、OnShowイベントがCM_DOCKCLIENTコントロール メッセージによって発生したことの証明です。ボタンをクリックすると、CM_DOCKCLIENTメッセージが実行され、Form2 のOnShowイベントが発生します。

Form1 のコード

procedure TForm1.FormShow(Sender: TObject);
begin
  Form2.Show;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  DockObject: TDragDockObject;
begin
  DockObject := TDragDockObject.Create(Form2);
  try
    // sending the CM_DOCKCLIENT message internally performs also the
    // CM_SHOWINGCHANGED message which triggers the TForm.OnShow event
    PageControl1.Perform(CM_DOCKCLIENT, WPARAM(DockObject), LPARAM(SmallPoint(0, 0)));
  finally
    DockObject.Free;
  end;
end;

そしてForm2にはOnShowイベントハンドラしかありません

procedure TForm2.FormShow(Sender: TObject);
begin
  ShowMessage('FormShow');
end;

簡単な回避策は、Form2 をそれ自体 (OnShowイベント内) で手動でドッキングするのではなく、作成者によって、またはそれを表示するフォームによってドッキングすることです。前の例では、Form1.OnShow イベントで Form2 を表示したので、そこに手動で簡単にドッキングできます。

procedure TForm1.FormShow(Sender: TObject);
begin
  Form2.Show;
  Form2.ManualDock(PageControl1);
end;

procedure TForm2.FormShow(Sender: TObject);
begin
  // no manual docking of this form by itself
end;
于 2011-12-08T18:20:55.387 に答える