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.

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top