Frage

Als Erweiterung von diese Frage:

Tform.onResize wird manchmal abgefeuert, bevor ein Formular zum ersten Mal gezeigt wird, aber nicht immer. Wenn BorderSyle beispielsweise entweder BSDIALOG oder BSNONE ist, wird OnResize nicht feuern. Für alle anderen BorderSyle -Werte (und mit allen anderen Eigenschaften bei ihren Ausfällen) feuert OnResize.

Gibt es andere Dinge, die sich auswirken, ob Onresize feuern wird, bevor das Formular angezeigt wird? Zum Beispiel können andere Eigenschaften oder Kombinationen von Eigenschaften dies beeinflussen?

Das Onresize -Ereignis ist ein Ergebnis der ShowWindow API -Funktion sendet a WM_SIZE Nachricht an das Fenster. Das wiederholt sich: Die Nachricht kommt von Windows, nicht von Delphi. Es ist eine Windows -Funktion (ShowWindow) Das sendet (manchmal) die Nachricht, die das Ereignis auslöst - sodass der VCL -Quellcode in diesem Fall nicht wirklich hilfreich ist.

Bonuspunkte für endgültige Antworten basierend auf dokumentierten ShowWindow / WM_SIZE Verhalten, z. B. Verweise auf MSDN -Dokumentation oder Petzold -Bücher.

War es hilfreich?

Lösung

Vielleicht hängt es sogar von den Anzeigeeinstellungen oder dem Desktop -Thema oder einer Windows -Version des Benutzers ab. Wenn Onresize mir solche Probleme geben würde, würde ich mein Programm aufbauen, um es immer zu erwarten und es in jeder Situation zu bewältigen, egal was ich für die Sache halte.

Andere Tipps

Ich glaube, dass OnResize feuern wird, wenn eine Ereignis eine Nachricht entsendet, in der besagt, dass die Form der Form (links, unten, Breite, Höhe) geändert wird.

Da Sie bereits herausgefunden haben, welche Nachricht dieses Ereignis abfeuert, müssen Sie jetzt verfolgen, wo die Nachricht in der VCL gesendet wird.

Schauen Sie sich den VCL -Quellcode an, um festzustellen, ob Sie diese Vorgänge erkennen können.

Bearbeiten: Lass uns niedrig gehen. Formulare in Windows (grob sprechen) haben das, was als "Fensterklasse" bezeichnet wird (es ist keine Klasse, wie wir es wissen. Alle Male wird die Fensterklasse des Formulars geändert (und Form ist sichtbar), das WM_SIZE wird gesendet.

Es wird also nicht all die Zeiten passieren, in denen das Formular angezeigt wird, aber nur die Dimensionen werden im Vergleich zur zugrunde liegenden Fensterklasse geändert.

Wie Sie beobachtet haben, ändern viele Eigenschaften Valuez die Dimensionen der Form (sogar einige Pixel).

Das ist ein Sehr oberflächlich Erklärung, das ist eine Menge anderer Details - aber ich verstehe, wie die Dinge "unter der Motorhaube" funktionieren.

Es gibt keinen Ersatz für Tests. Wie wäre es, wenn Sie ein Formular in Code erstellen, die Eigenschaften festlegen, an denen Sie interessiert sind, und aufzunehmen, wenn das Ereignis der Größenänderung aufgerufen wird.

Wenn Sie die Hässlichkeit des Codes entschuldigen, finden Sie hier einen groben Beweis für das Konzept, das alle Kombinationen von BorderSyle und Position testet, ohne für jeden explizit zu kodieren. Sie können mehr Eigenschaften hinzufügen und so weit Sie möchten. Ein Werkzeug wie Codesit würde auch den Protokollierungsreiniger und auch einfacher machen.

Erstellen Sie eine Anwendung mit 2 Formularen. Stellen Sie sicher, dass der zweite nicht automatisch geschaffen wird.

Fügen Sie in der zweiten Form eine Eigenschaft hinzu und fügen Sie dem Ereignis der Größe des Formulars einen kleinen Protokollierungscode hinzu:

  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;

Fügen Sie in der Hauptform die Typinfo in die Verwendungsklausel hinzu und lassen Sie eine Taste und ein Memo auf das Formular fallen.

Fügen Sie eine einfache Prozedur hinzu:

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

Fügen Sie nun das ButtonClick -Ereignis Folgendes hinzu:

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;

Sie werden feststellen, dass die Größe der Größe der Größe von Bränden angegeben wird, wenn einige Eigenschaften vor dem angezeigten Formular festgelegt werden, und ich sehe, dass in einigen Kombinationen die Größe der Größe zweimal zu schießen scheint, wenn das Formular angezeigt wird. Interessant.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top