作为this question的扩展名:
TForm.OnResize有时会在首次显示表单之前触发,但并非总是如此。例如,如果BorderStyle是bsDialog或bsNone,则OnResize将不会触发。对于所有其他BorderStyle值(以及其默认值下的所有其他属性),OnResize会触发。
在显示表单之前是否还会影响OnResize是否会触发?例如,其他属性或属性组合会对此产生影响吗?
OnResize事件是ShowWindow
API函数向窗口发送WM_SIZE
消息的结果。这有点重复:消息来自Windows,而不是来自Delphi。这是一个Windows函数(ShowWindow
),它(有时)发送触发事件的消息 - 所以VCL源代码在这种情况下,代码并没有真正的帮助。
基于记录的ShowWindow
/ WM_SIZE
行为的明确答案的奖励积分,例如:参考MSDN文档或Petzold书籍。
答案 0 :(得分:1)
可能甚至取决于用户的显示设置或桌面主题或Windows版本。如果OnResize给我这样的问题,我会建立我的程序,总是期待它并在任何情况下处理它,无论我认为是什么原因。
答案 1 :(得分:0)
我相信OnResize会在事件发送消息时触发 说将修改表格大小(左,底,宽,高)。
由于您已经发现了哪个消息触发了该事件,因此您需要 现在跟踪在vcl中发送消息的位置。
查看vcl源代码,了解是否可以发现这些操作。
编辑:让我们走低级别。窗户中的表格(粗略地说话)有什么 被称为“窗口类”(它不是像我们所知的那样的类)。所有时候窗体的窗口类都被调整大小(并且窗体是可见的),WM_SIZE被发送。
因此,不会一直显示表单,但与底层窗口类相比,只会更改它的尺寸。
正如您所观察到的,许多属性值会改变表单的尺寸(甚至几个像素)。
这是一个非常肤浅的解释,这是其他一些细节 - 但是我理解了事情是如何工作的。“
答案 2 :(得分:0)
没有替代测试。如何在代码中创建表单,设置您感兴趣的属性以及在调用resize事件时进行记录。
如果您原谅代码的丑陋,这里是一个粗略的概念证明,它可以测试BorderStyle和Position的所有组合,而无需为每个组合明确编码。您可以添加更多属性并随意使用。像CodeSite这样的工具也会使日志记录更清晰,更容易。
使用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;
在主窗体中,将TypInfo添加到uses子句并在窗体上放置一个按钮和一个备忘录。
添加一个简单的程序:
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似乎会触发两次。有趣。