Question

Dans le prolongement de cette question :

TForm.OnResize est parfois déclenché avant une forme est d'abord montré, mais pas toujours. Par exemple, si BorderStyle est soit bsDialog ou bsNone, puis OnResize ne se déclenche pas. Pour toutes les autres valeurs de BorderStyle (et toutes les autres propriétés à leurs valeurs par défaut), OnResize ne se déclenche.

Y at-il d'autres choses qui déterminent si OnResize se déclenche avant que le formulaire est affiché? Par exemple, d'autres propriétés, ou des combinaisons de propriétés, qui peuvent affecter cela?

L'événement OnResize est un résultat de la fonction API ShowWindow envoyer un message WM_SIZE à la fenêtre. Ce répéter:. le message provient de Windows pas de Delphi Il est une fonction Windows (ShowWindow) qui est (parfois) d'envoyer le message qui déclenche l'événement - de sorte que le code source VCL est pas vraiment utile dans ce cas.

Les points bonus pour des réponses définitives basées sur le comportement ShowWindow / WM_SIZE documenté, par exemple références à la documentation MSDN ou des livres Petzold.

Était-ce utile?

La solution

Peut-être même dépend des paramètres d'affichage de l'utilisateur ou le thème bureau ou une version de Windows. Si OnResize me donnaient des problèmes comme ça, je bâtirai mon programme d'attendre toujours et le manipuler en toute situation, peu importe ce que je pense être la cause.

Autres conseils

Je crois que OnResize se déclenche lorsqu'un événement expédier un message dire que la taille de la forme (gauche, bas, largeur, hauteur) sera modifiée.

Puisque vous avez déjà découvert un message qui déclenche cet événement, vous avez besoin maintenant trace où le message est envoyé dans le vlc.

Regardez le code source de vlc pour voir si vous pouvez repérer ces opérations.

Edit: allons bas niveau. Formes dans les fenêtres (parler grossièrement) ont ce est appelée « classe de fenêtre » (ce n'est pas une classe comme nous le connaissons oop). Toutes les heures de la classe de la fenêtre du formulaire est redimensionnée (et la forme est visible), le WM_SIZE est envoyé.

Il ne se produira pas toutes les fois que le formulaire est indiqué, mais seulement les dimensions du celui-ci sont modifiées par rapport à la classe de fenêtre sous-jacente.

Comme vous l'avez observé, de nombreuses propriétés valuez modifier les dimensions de la forme (même quelques pixels).

Ceci est un très superficielle explication, qui est une tonne d'autres détails - mais je crois savoir comment les choses fonctionne « sous le capot »

.

Il n'y a pas de substitut pour les tests. Que diriez-vous de créer un formulaire dans le code, la définition des propriétés qui vous intéressent et l'enregistrement lorsque l'événement resize est appelé.

Si vous excuserez la laideur du code, voici une preuve approximative du concept qui teste toutes les combinaisons de BorderStyle et position sans codage explicitement pour chacun. Vous pouvez ajouter des propriétés et prendre aussi loin que vous le souhaitez. Un outil comme CodeSite rendrait le nettoyeur de l'exploitation forestière et plus facile aussi.

Créer une application avec 2 formes. Assurez-vous que le second est pas créé automatiquement.

Dans la seconde forme, ajoutez une propriété et ajouter un peu de code d'enregistrement à l'événement Resize du formulaire:

  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;

Dans la principale forme, ajouter TypInfo à la clause uses et déposez un bouton et une note sur le formulaire.

Ajouter une procédure simple:

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

Maintenant, ajoutez ce qui suit à l'événement 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;

Vous remarquerez que redimensionnez se déclenche lorsque certaines propriétés sont définies avant que le formulaire est affiché, et je vois que dans certaines combinaisons, redimensionnez semble tirer deux fois lorsque le formulaire est affiché. Intéressant.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top