Sob quais condições um incêndio no Tormizará em exibição?
Pergunta
Como uma extensão de essa questão:
Às vezes o TFFORM.OrSize é disparado antes que um formulário seja mostrado pela primeira vez, mas nem sempre. Por exemplo, se o BordersTyle for Bsdialog ou Bsnone, o OnResize não disparará. Para todos os outros valores de BordersTyle (e com todas as outras propriedades em seus padrões), o OnResize dispara.
Existem outras coisas que afetam se o aumento do fogo será o fogo antes que o formulário seja mostrado? Por exemplo, outras propriedades ou combinações de propriedades que podem afetar isso?
O evento OnResize é resultado do ShowWindow
Função da API enviando um WM_SIZE
mensagem para a janela. Isso leva a repetição: A mensagem vem do Windows, não da Delphi. É uma função do Windows (ShowWindow
) Essa é (às vezes) enviar a mensagem que aciona o evento - para que o código -fonte VCL não seja realmente útil neste caso.
Pontos de bônus para respostas definitivas com base em documentados ShowWindow
/ WM_SIZE
comportamento, por exemplo, referências à documentação do MSDN ou livros de Petzold.
Solução
Talvez até dependa das configurações de exibição do usuário ou do tema da área de trabalho ou da versão do Windows. Se o OnResize estivesse me dando problemas como esse, eu construiria meu programa para sempre esperar e lidar com isso em qualquer situação, não importa o que eu pense ser a causa.
Outras dicas
Acredito que o OnResize disparará quando um evento despachar uma mensagem dizendo que o tamanho do formulário (esquerda, inferior, largura, altura) será modificado.
Como você já descobriu qual mensagem dispara esse evento, agora precisa rastrear onde a mensagem é enviada no VCL.
Veja o código -fonte VCL para ver se você pode identificar essas operações.
EDIT: Vamos ir de nível baixo. Os formulários no Windows (falando grosseiramente) têm o que é chamado de "classe de janela" (não é uma classe como a conhecemos). Todas as vezes a classe de janela do formulário é redimensionada (e o formulário é visível), o WM_SIZE é enviado.
Portanto, isso não acontecerá todas as vezes em que o formulário é mostrado, mas apenas as dimensões de ITs são alteradas em comparação com a classe de janela subjacente.
Como você observou, muitas propriedades Valuez alteram as dimensões da forma (até alguns pixels).
Isto é um muito superficial Explicação, isso é uma tonelada de outros detalhes - mas é meu entendimento como as coisas funcionam "sob o capô".
Não há substituto para testes. Que tal criar um formulário no código, definir as propriedades em que você está interessado e gravação quando o evento de redimensionamento é chamado.
Se você desculpar a feiúra do código, aqui está uma prova de conceito que testa todas as combinações de BordersTyle e posição sem codificar explicitamente para cada um. Você pode adicionar mais propriedades e levá -lo até onde quiser. Uma ferramenta como o Codesite facilitaria o limpeza e mais fácil.
Crie um aplicativo com 2 formulários. Verifique se o segundo não é criado automaticamente.
No segundo formulário, adicione uma propriedade e adicione um pequeno código de registro ao evento de redimensionamento do formulário:
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;
Na forma principal, adicione o tipinfo à cláusula de usos e solte um botão e um memorando no formulário.
Adicione um procedimento simples:
procedure TForm1.ResizeDetected(Sender: TObject);
begin
Memo1.Lines.Add(' *** Resize detected');
end;
Agora adicione o seguinte ao evento 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;
Você notará que redimensione incêndios quando algumas propriedades forem definidas antes que o formulário seja mostrado, e vejo que em algumas combinações, redimensionar parece disparar duas vezes quando o formulário é mostrado. Interessante.