¿Bajo qué condiciones un TForm activará OnResize en exhibición?
Pregunta
Como una extensión de esta pregunta:
TForm.OnResize a veces se activa antes de que se muestre un formulario por primera vez, pero no siempre.Por ejemplo, si BorderStyle es bsDialog o bsNone, OnResize no se activará.Para todos los demás valores de BorderStyle (y con todas las demás propiedades en sus valores predeterminados), OnResize se activa.
¿Hay otras cosas que afectan si OnResize se activará antes de que se muestre el formulario? Por ejemplo, ¿otras propiedades o combinaciones de propiedades que pueden afectar esto?
El evento OnResize es el resultado de la ShowWindow
Función API que envía un WM_SIZE
mensaje a la ventana.Vale la pena repetirlo: el mensaje proviene de Windows, no de Delphi. Es una función de Windows (ShowWindow
) que (a veces) envía el mensaje que desencadena el evento, por lo que el código fuente de VCL no es realmente útil en este caso.
Puntos de bonificación por respuestas definitivas basadas en documentación. ShowWindow
/ WM_SIZE
comportamiento, p.e.referencias a documentación de MSDN o libros de Petzold.
Solución
Tal vez sea aún dependen de la configuración o de escritorio tema de la pantalla del usuario o de la versión de Windows. Si OnResize me estaban dando problemas como éste, me gustaría crear mi programa a esperar siempre y manejarlo en cualquier situación, no importa lo que yo creo que es la causa.
Otros consejos
Creo que OnResize se disparará cuando un evento despachar un mensaje diciendo que el tamaño de la forma (izquierda, abajo, anchura, altura) será modificado.
Dado que ya descubierto cuál es el mensaje que dispara caso, es necesario Ahora trace donde el mensaje se envía en el VCL.
Mira el código fuente VCL para ver si puede detectar esas operaciones.
Editar: vamos a ir bajo nivel. Formas en las ventanas (groseramente hablando) lo tienen se llama "clase de ventana" (que no es una clase como la conocemos POO). Todas las horas se cambia el tamaño de la clase de la ventana de la forma (y la forma es visible), se envía el WM_SIZE.
Por lo tanto, no va a pasar todas las veces que se muestra el formulario, pero sólo el árbitro pita dimensiones se cambian en comparación con la clase de ventana subyacente.
Como se ha observado, muchas propiedades valuez cambiar las dimensiones de la forma (incluso unos pocos píxeles).
Este es un muy superficial explicación, eso es un montón de otros detalles - pero es mi comprensión de cómo funciona cosas "bajo el capó"
.No hay sustituto para la prueba. ¿Qué hay de la creación de un formulario en el código, establecer las propiedades que le interesan y grabando cuando el evento de cambio de tamaño se llama.
Si me disculpa la fealdad del código, he aquí una prueba aproximada del concepto que pone a prueba todas las combinaciones de EstiloDeLosBordes y posición sin necesidad de programación explícita para cada uno. Se pueden añadir más propiedades y llevarlo tan lejos como desee. Una herramienta como CodeSite haría que el limpiador de registro y más fácil, también.
Crea una aplicación con 2 formas. Asegúrese de que la segunda no es auto-creado.
En la segunda forma, añadir una propiedad y añadir un poco de código de registro de evento de cambio de tamaño de la forma:
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;
En la forma principal, añadir TypInfo a la cláusula de usos y soltar un botón y una nota en la forma.
Añadir un procedimiento simple:
procedure TForm1.ResizeDetected(Sender: TObject);
begin
Memo1.Lines.Add(' *** Resize detected');
end;
Ahora agregue el siguiente al 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;
Se dará cuenta de que cambiar el tamaño de los incendios cuando algunas propiedades se establecen antes de que aparezca el formulario, y veo que en algunas combinaciones, cambiar el tamaño parece disparar dos veces cuando se muestra el formulario. Interesante.