TForm はどのような条件下でショーで OnResize を起動しますか?
質問
の延長として この質問:
TForm.OnResize はフォームが最初に表示される前に起動されることがありますが、常に起動されるわけではありません。たとえば、BorderStyle が bsDialog または bsNone の場合、OnResize は起動しません。他のすべての BorderStyle 値 (および他のすべてのプロパティがデフォルトの場合) では、OnResize が起動されます。
フォームが表示される前に OnResize が起動するかどうかに影響を与えるものは他にもありますか? たとえば、これに影響を与える可能性のある他のプロパティ、またはプロパティの組み合わせはありますか?
OnResize イベントは、 ShowWindow
API 関数が送信する WM_SIZE
窓口へのメッセージ。それは繰り返します: メッセージは Delphi からではなく Windows から送信されています。 Windows の機能です (ShowWindow
) これは、(場合によっては) イベントをトリガーするメッセージを送信しているため、この場合、VCL ソース コードはあまり役に立ちません。
文書に基づいた最終的な回答にはボーナスポイント ShowWindow
/ WM_SIZE
行動、例:MSDN ドキュメントまたはペッツォルトの書籍への参照。
解決
たぶんそれもユーザーの表示設定やデスクトップテーマやWindowsのバージョンによって異なります。さらにonResizeが私にこのような問題を与えていた場合、私は関係なく、私が原因であることをどう思うか、常にそれを期待し、どのような状況でそれを処理するために、私のプログラムを構築しないでしょう。
他のヒント
イベントがフォームサイズ(左、下、幅、高さ)が変更されるというメッセージをイベントで派遣すると、Onresizeが発射されると思います。
どのメッセージがそのイベントを発射するかをすでに発見したので、VCLでメッセージが送信される場所をトレースする必要があります。
vcl ソース コードを調べて、これらの操作を見つけられるかどうかを確認してください。
編集:低レベルに行きましょう。Windowsのフォーム(ひどく話している)には、「ウィンドウクラス」と呼ばれるものがあります(私たちが知っているようなクラスではありません)。フォームのウィンドウ クラスのサイズが変更される (フォームが表示される) たびに、WM_SIZE が送信されます。
したがって、フォームが表示されるたびにこの問題が発生するわけではありませんが、基になるウィンドウ クラスと比較してその寸法のみが変更されます。
ご覧のとおり、多くのプロパティ valuez はフォームの寸法を (数ピクセルでも) 変更します。
これは 非常に表面的な 説明すると、その他にも詳細はたくさんありますが、物事が「内部で」どのように機能するかは私の理解です。
テストに代わるはありません。どのように、コードでフォームを作成し、あなたが興味を持っているプロパティを設定し、resizeイベントが呼び出されたときに記録について。
あなたは、コードの醜さを失礼した場合、、ここに明示的に各1をコードなしでのBorderStyleと位置のすべての組み合わせをテストコンセプトのラフな証拠です。あなたはより多くのプロパティを追加し、限り、あなたが好きなようにそれを取ることができます。コードサイトのようなツールは、あまりにも、ログクリーナーを作り、簡単になります。
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;
あなたは、フォームが表示される前に、いくつかのプロパティが設定されているときには、火災のサイズを変更するに気づくでしょう、と私はいくつかの組み合わせで、サイズを変更することがわかり、フォームが表示されたときに二回起動するように思えます。面白います。