Domanda

Come estensione di questa domanda :

TForm.OnResize a volte è sparato prima che un modulo viene prima mostrato, ma non sempre. Per esempio, se è o BorderStyle bsDialog o bsNone, allora OnResize sarà si attiva. Per tutti gli altri valori BorderStyle (e con tutte le altre proprietà ai loro valori di default), OnResize fa fuoco.

Ci sono altre cose che influenzano se OnResize scatterà prima che venga visualizzato il modulo? Ad esempio, altre proprietà, o combinazioni di proprietà, che possono influenzare questo?

L'evento OnResize è il risultato della funzione ShowWindow API inviando un messaggio WM_SIZE alla finestra. Che reca ripetendo:. il messaggio proviene da Windows, non da Delphi Si tratta di una funzione di Windows (ShowWindow) che è (a volte) inviare il messaggio che attiva l'evento - in modo che il codice sorgente VCL non è davvero utile in questo caso.

I punti di bonus per le risposte definitive sulla base di ShowWindow documentato / comportamento WM_SIZE, per esempio riferimenti alla documentazione MSDN o libri Petzold.

È stato utile?

Soluzione

Forse è anche dipendono in mostra impostazioni o tema del desktop dell'utente o la versione di Windows. Se OnResize mi davano problemi come questo, vorrei costruire il mio programma di aspettarsi sempre e gestire in ogni situazione, non importa quello che penso di essere la causa.

Altri suggerimenti

Credo che OnResize si attiva quando un evento inviare un messaggio dicendo che taglia forma (a sinistra, in basso, larghezza, altezza) viene modificato.

Dal momento che già scoperto che un messaggio incendi che evento, è necessario ora traccia in cui il messaggio viene inviato nella VCL.

guardare il codice sorgente di VCL per vedere se è possibile individuare tali operazioni.

Modifica: andiamo a basso livello. Forme in finestre (grossolanamente parlando) hanno quello si chiama "classe di finestra" (non è una classe come la conosciamo OOP). Tutte le volte la classe di finestra del form viene ridimensionato (e la forma è visibile), il WM_SIZE viene inviato.

Quindi non accadrà tutte le volte il modulo è mostrato, ma solo dimensioni del IT sono cambiato rispetto classe finestra sottostante.

Come avete osservato, molte proprietà valuez cambiare le dimensioni del modulo (anche un paio di pixel).

Questo è un molto superficiale spiegazione, che è una tonnellata di altri dettagli - ma è la mia comprensione di come funziona cose "sotto il cofano"

.

Non c'è sostituto per il test. Che ne dite di creare un modulo in codice, impostare le proprietà che ti interessa e la registrazione quando l'evento resize viene chiamato.

Se vuoi scusare la bruttezza del codice, ecco una prova approssimativa di concetto che mette alla prova tutte le combinazioni di Stile bordo e di posizione senza esplicitamente che codifica per ciascuno di essi. È possibile aggiungere più proprietà e portarlo per quanto ti piace. Uno strumento come CodeSite renderebbe il pulitore di registrazione e più facile, anche.

Creare un'applicazione con 2 forme. Assicurarsi che il secondo non è auto-creato.

Nel secondo modulo, aggiungere una proprietà e aggiungere un po 'di codice di registrazione all'evento Ridimensionamento del form:

  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;

Nel modulo principale, aggiungere TypInfo alla clausola di usi e rilasciare un pulsante e una nota sul modulo.

Aggiungi una procedura semplice:

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

A questo punto aggiungere il seguente all'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;

Si noterà che ridimensionare incendi quando alcune proprietà sono impostate prima che viene mostrata la forma, e vedo che in alcune combinazioni, ridimensionare sembra di sparare due volte quando viene visualizzato il modulo. Interessante.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top