4

この質問の延長として:

TForm.OnResizeは、フォームが最初に表示される前に発生することがありますが、常に発生するとは限りません。たとえば、BorderStyleがbsDialogまたはbsNoneの場合、OnResizeは起動しません。他のすべてのBorderStyle値(および他のすべてのプロパティがデフォルト)の場合、OnResizeは起動します。

フォームが表示される前にOnResizeが起動するかどうかに影響する他の事柄はありますか?たとえば、これに影響を与える可能性のある他のプロパティ、またはプロパティの組み合わせ?

OnResizeイベントは、ShowWindowAPI関数WM_SIZEがウィンドウにメッセージを送信した結果です。繰り返しになりますが、メッセージはDelphiからではなく、Windowsから送信されます。これは、イベントをトリガーするメッセージを(場合によっては)送信するWindows関数(ShowWindow)であるため、この場合、VCLソースコードはあまり役に立ちません。

ShowWindow文書化された/動作に基づく決定的な回答のボーナスポイントWM_SIZE。たとえば、MSDNドキュメントやPetzoldの本への参照。

4

3 に答える 3

1

ユーザーのディスプレイ設定、デスクトップ テーマ、または Windows のバージョンに依存する場合もあります。OnResize でこのような問題が発生した場合、原因が何であれ、常にそれを予期して処理するようにプログラムを作成します。

于 2009-08-15T21:51:54.067 に答える
0

フォームのサイズ (左、下、幅、高さ) が変更されるというメッセージをイベントがディスパッチすると、OnResize が起動すると思います。

どのメッセージがそのイベントを起動するかは既にわかっているので、今度はメッセージが vcl のどこに送信されたかを追跡する必要があります。

vcl ソース コードを見て、これらの操作を見つけられるかどうかを確認してください。

編集:低レベルに行きましょう。ウィンドウ内のフォーム (大雑把に言えば) には、「ウィンドウ クラス」と呼ばれるものがあります (これは、私たちが知っているようなクラスではありません)。フォームのウィンドウ クラスのサイズが変更される (およびフォームが表示される) たびに、WM_SIZE が送信されます。

したがって、フォームが表示されるたびに発生するわけではありませんが、基になるウィンドウ クラスと比較してその寸法のみが変更されます。

お気づきのように、多くのプロパティ valuez がフォームの寸法を変更します (数ピクセルでも)。

これは非常に表面的な説明であり、他にも多くの詳細がありますが、「フードの下で」物事がどのように機能するかを理解しているのは私の理解です.

于 2009-08-06T21:21:23.477 に答える
0

テストに代わるものはありません。コードでフォームを作成し、関心のあるプロパティを設定し、サイズ変更イベントが呼び出されたときに記録するのはどうですか。

コードの醜さを許すなら、BorderStyle と Position のすべての組み合わせを、それぞれを明示的にコーディングせずにテストする大まかな概念実証を次に示します。さらにプロパティを追加して、好きなだけ取得できます。CodeSite のようなツールを使用すると、ロギングもよりクリーンで簡単になります。

2 つのフォームでアプリケーションを作成します。2 番目のものが自動作成されていないことを確認してください。

2 番目のフォームでは、プロパティを追加し、フォームの Resize イベントに小さなログ コードを追加します。

  private
    FOnResizeFired: TNotifyEvent;
  public
    property OnResizeFired: TNotifyEvent read FOnResizeFired write FOnResizeFired;
  end;

...

procedure TForm2.FormResize(Sender: TObject);
begin
  if Assigned(FOnResizeFired) then
    FOnResizeFired(self);
end;

メインフォームの uses 句に TypInfo を追加し、ボタンとメモをフォームにドロップします。

簡単な手順を追加します。

procedure TForm1.ResizeDetected(Sender: TObject);
begin
  Memo1.Lines.Add('    *** Resize detected');
end;

次に、ButtonClick イベントに次を追加します。

procedure TForm1.Button1Click(Sender: TObject);
var
  lBorderStyle: TFormBorderStyle;
  lBorderStyleName: string;
  lPosition: TPosition;
  lPositionName: string;
  lForm: TForm2;
begin
  Memo1.Clear;
  for lBorderStyle in [low(TFormBorderStyle) .. high(TFormBorderStyle)] do
  begin
    for lPosition in [low(TPosition) .. high(TPosition)] do
    begin
      lBorderStyleName := GetEnumName(TypeInfo(TFormBorderStyle), Integer(lBorderStyle));
      lPositionName := GetEnumName(TypeInfo(TPosition), Integer(lPosition));
      Memo1.Lines.Add(Format('Border: %s  Position: %s', [lBorderStyleName, lPositionName]));

      Memo1.Lines.Add('  Creating form');
      lForm := TForm2.Create(self);
      try
        Memo1.Lines.Add('  Form Created');
        lForm.OnResizeFired := ResizeDetected;
        Memo1.Lines.Add('    Setting border style');
        lForm.BorderStyle := lBorderStyle;
        Memo1.Lines.Add('    Setting Position');
        lForm.Position := lPosition;
        Memo1.Lines.Add('    Showing form');
        lForm.Show;
        Memo1.Lines.Add('    Form Shown');
        lForm.Close;
        Memo1.Lines.Add('    Form Closed');
      finally
        FreeAndNil(lForm);
        Memo1.Lines.Add('    Form Freed');
      end;
    end;
  end;
end;

フォームが表示される前にいくつかのプロパティが設定されていると resize が起動することに気付くでしょう。いくつかの組み合わせでは、フォームが表示されるときに resize が 2 回起動するように見えます。面白い。

于 2009-08-07T13:07:53.243 に答える