PDA

Ver la Versión Completa : Codigo antes de mostrar form - Maximizar


lafirma
07-06-2004, 23:32:11
Mi app es MDI, tengo un pequeño componente que guarda la configuracion de posicion de los forms, funciona bastante bien, pero tengo un problema:
Cuando la posicion del form es recuperada y su ultimo estado era maximizado se produce un molesto efecto, aparece el form normal e inmediatamente se maximiza, produciendo el molesto efecto que menciono, en este hilo (http://www.clubdelphi.com/foros/showthread.php?t=8831&highlight=maximizar) se habla del asunto pero no es exactamente la solucion en la que estoy pensando.

El efecto se produce si establezco la propiedad WindowState desde el inspector de objetos, y tambien si lo hago en el create del form, pues al ser mis forms MDIChild al solo crearlos se muestran por si solos sin necesidad de una llamada al metodo Show o ShowModal.

Debido a esto quiero incorporar el codigo del componente en la clase base que uso para todos mis forms (de la cual todos heredan), sobreescribiendo un metodo que sea ejecutado antes de mostrar el form.
Que metodo deberia sobrescribir para que los forms sean creados maximizados de forma automatica?

roman
07-06-2004, 23:37:26
Que metodo deberia sobrescribir para que los forms sean creados maximizados de forma automatica?

Creo que te bastaría redefinir el constructor Create.

// Saludos

lafirma
08-06-2004, 01:03:33
Roman, agaradezco tu atencion a mi problema
He intentado ya lo que mencionas y siempre se presenta el mismo problema:
El codigo siguiente funciona (Maximiza el form) pero siempre se presenta el problema del efecto, supongo que este codigo es como establecer la propiedad inmediatamente despues de la llamada a Create cuando creo el form en tiempo de ejecucion..

constructor TBaseForm.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
WindowState := wsMaximized;
end;


este codigo no funciona para nada... no se maximiza, supongo que la llamada a inherited sobreescribe el valor de la propiedad WindowState.

constructor TBaseForm.Create(AOwner: TComponent);
begin
WindowState := wsMaximized;
inherited Create(AOwner);
end;


Mas bien quisiera poder establecer desde delphi que la ventana se cree maximizada desde la llamada que se hace al API de Windows cuando se crea el objeto del form.

roman
08-06-2004, 02:10:43
Dime, ¿en que Windows lo pruebas? Es que es un poco difícil verificarlo porque en WinXP no se muestra el efecto que mencionas. Miraré a ver si puedo probarlo en Windows 98.

// Saludos

roman
08-06-2004, 03:39:57
Vamos a ver.

El efecto que mencionas supongo que es el de la animación que normalmente tienen las ventanas al maximizarse. No lo había notado porque sólo probé con el primer formulario hijo que se crea de inicio. Pero al hacer la prueba con formularios creados durante la ejecución vi que en efecto se nota como la ventana se va maximizando.

Ya en el hilo que mencionas, Magician comentaba que este efecto se puede deshabilitar. Quizá lo que no te gustó de esa solución es que sólo menciona como hacerlo cambiando las propiedades en el panel de control.

Sin embargo puedes hacer lo mismo por código con el siguiente procedimiento:


(*
Enable = false inhabilita la animación
Enable = true habilita la animación
*)
procedure EnableAnimation(Enable: Boolean);
var
Info: TAnimationInfo;

begin
Info.cbSize := SizeOf(TAnimationInfo);
LongBool(Info.iMinAnimate) := Enable;
SystemParametersInfo(SPI_SETANIMATION, SizeOf(Info), @Info, 0);
end;


Usando este procedimiento justo antes de crear una nueva ventana hija se mejora bastante y prácticamente desaparece el efecto. Sin embargo aún se alcanza a notar como la ventana pasa de su tamaño normal al maximizado. El parpadeo es muy rápido y muchas veces no se nota pero aún deja la sensación de que algo "no anda bien".

No obstante puedes hacer uso de otro truco más- LockWindowUpdate, con lo que, hasta donde he visto, desaparece totalmente el efecto. LockWindowUpdate sirve para deshabilitar el dibujado de una ventana de manera que la ventana hija no se vea sino hasta que esté completamente maximizada.

De hecho, LockWindowUpdate fue lo primero que intenté pero aunque ciertamente no se ve el efecto de la maximización, lo que sucede es que la ventana tarda unos cuántos microsegundos en aparecer, justamente por el tiempo que se lleva la animación.

Pero combinando ambas técnicas me parece que se logra lo que deseas.

Para centralizar el proceso podrías crearte un método en el formulario padre que se encargue de crear las ventanas hijas:


type
TVentanaPadre = class(TForm)
public
procedure CreaHija(ClaseHija: TFormClass);
end;

implementation

procedure TVentanaPadre.CreaHija(ClaseHija: TFormClass);
begin
LockWindowUpdate(Handle);
EnableAnimation(false);

try
ClaseHija.Create(Self);
finally
EnableAnimation(true);
LockWindowUpdate(0);
end;
end;

end.


En el parámetro ClaseHija pasarías la clase de la ventana mdi hija de manera que el mismo procedimiento te sirve si manejas varias clases de ventanas hijas.

// Saludos

yusnerqui
08-06-2004, 15:49:22
Waoooo, quiero darte las gracias Román, yo fui quien abrió aquel hilo y te confieso que aunque quedé muy agradecido por el esfuerzo de todos los amigos del club mi aplicación no funcionó como yo quería hasta hoy que puse en práctica los trucos que das en este hilo. Gracias nuevamente.

Por cierto de donde lo sacarías :confused:

un saludo desde Cuba;)

lafirma
08-06-2004, 18:08:18
Roman, he observado tus ejemplos y funcionan a la perfeccion... agradezco tu evidente esfuerzo por encontrar una solucion...

Sin embargo debo mencionar que aun tengo contratiempos, pues el hecho de que el form sea maximizado ó no, se obtiene de un archivo Ini cada vez que se abren los forms, y se guarda cada vez que se cierran, por lo que los trucos mencionados no me funcionan tal cual estan, esoy intentando adaptarlos a lo que necesito, indicare mas adelante como resulto todo.

delphi.com.ar
08-06-2004, 18:12:05
¿De que componente se trata?... si es alguno de los de las RxLibs, puedes suprimir este comportamiento simplemente quitando fpState de la propiedad Options.

lafirma
08-06-2004, 18:36:31
Es un componente personal, lo uso para recuperar el estado del form de una manera sencilla, le eche un vistazo al componente de las Rx que mencionas, no recordaba que las Rx tenian ese componente, yo solo uso los CurrencyEdit, CalcEdit y DateEdit junto con sus versiones DBAware...
De todas maneras al establecer el State en la propiedad Options lo que hace es que desactiva la capacidad de recuperar tambien el estado del form cuando se cerro, yo no quiero eso, el 'componentio' :p que tengo funciona como yo quiero, guarda y recupera todo, eso incluye estado, posicion y tamaño. El unico problemilla es el efecto ese que se produce al maximizar,
En un cliente que no tiene una maquina tan potente se ve mas 'real', aparece maximizado, se ubica en normal y despues nuavamente se maximiza, y se ve fatal... el cliente no dice nada de eso, ni le para mucho balin como decimos por aca, pero simplemente a mi no me deja satisfecho... quiero que se vea ya maximizado desde que el form aparece.

Intenté sobrescribiendo en la clase el metodo CreateParams, pero tampoco funciona... seguire investigando a ver que consigo...

roman
08-06-2004, 18:39:35
por lo que los trucos mencionados no me funcionan tal cual estan, esoy intentando adaptarlos a lo que necesito, indicare mas adelante como resulto todo.

En casa tengo algún código que se encargaba de estos detalles sin importar en qué momento se maximizaba el formulario. No puedo verificarlo ahora pero pienso que puedes intentar capturar el mensaje WM_SIZE para el formulario hijo, inhabilitando la animación antes de llamar a inherited y rehabilitandola después:


procedure TVentanaHija.WMSize(var Msg: TWMSize);
begin
if Msg.SizeType = SIZE_MAXIMIZED then
begin
EnableAnimation(false);
LockWindowUpdate(Handle);

inherited;

LockWindowUpdate(0);
EnableAnimation(true);
end
else
inherited;
end;


Si esto te funciona entonces bastaría que manejes este mensaje en el formulario base de manera que todos los hijos descendientes hereden el comportamiento.

Claro, que si no te interesa recuperar la maximización al momento de reabrir la aplicación entonces bastará hacer lo que te indica Federico.

Edición - Corrección

En la llamada a LockWindowUpdate de arriba tendrías que poner el 'handle' de la ventana padre, no el del mismo formulario hijo como puse.

// Saludos

lafirma
08-06-2004, 18:57:06
veo que ya voy encontrando la luz...
Roman, esto ya se ve mejor...
En cuanto a tu codigo editado, tienes razon, si es el handle hijo el que se ubica pues no surte ningun efecto...

Por otro lado, delphi.com, a raiz de tu mensaje estuve viendo el componenente de las Rx y realmente es muy potente... trae incluso su propio diseñador...

Debo decir que esto me tiene un poco desconcertado, deberia existir una manera de crear el form maximizado desde el inicio y no que se efectue la creacion como normal y despues se maximize... eso fue lo que intente al sobreescribir el metodo createparams pero tampoco funciona...

gracias de nuevo

delphi.com.ar
08-06-2004, 19:05:35
Por otro lado, delphi.com, a raiz de tu mensaje estuve viendo el componenente de las Rx y realmente es muy potente... trae incluso su propio diseñador...Cometí el error de no leer todo tu mensaje, y entendí que otro era el problema, por eso mi sugerencia. Con respecto a estos componentes de las Rx, se trata de dos componentes, uno con una potencialidad extra muuuy interesante. El TFormPlacement, sirve para guardar la posición, estado y posición del foco de un formulario, pudiendo extender a otras propiedades de otros componentes o simplemente variables desde los eventos OnSavePlacement y OnRestorePlacement con los métodos Write.. y Read.., y el TFormStorage trae un editor de propiedades que nos permite guardar el valor casi cualquier propiedad de los componentes contenidos por el formulario. Otra ventaja de estos controles, es que estan soportados por algunos componentes como el TRxDBGrid y pueden enlazarse con este para que se guarde automáticamente el ancho y posición de las columnas...

Saludos!

JXJ
18-11-2005, 21:52:34
Roman. '¿de donde conoces que hacen esas funciones?

estuve buscando en la ayuda de delphi
y en internet.
pero no encuentro, lo de
lockwindow
EnableAnimation(false);

y nada,. yo solo quiero deshabilitar el ver
la animacion.

ya revise aui.
http://www.clubdelphi.com/foros
/showthread.php?t=8831&highlight=maximizar

y esta bueno, el poner windowstate:= wsmaximized

vale gracias. :D

roman
18-11-2005, 22:32:21
EnableAnimation no la encontrarás porque es sólo el nombre que le puse yo a la función de más arriba, que usa SystemParametersInfo. Tanto esta última como LockWindowUpdate están documentadas en el SDK de Windows (http://msdn.microsoft.com/library/default.asp).

// Saludos

JXJ
19-11-2005, 05:42:33
Gracias. Roman

Como que ya soñe. el leer tu reespuesta.

JXJ
30-07-2006, 06:29:46
¿como obtengo En la llamada a LockWindowUpdate de arriba el 'handle' de la ventana padre, no el del mismo formulario hijo ?

no doy como hacerlo.. de varias formas he intendado
que no se muestre la animacion pero siempre
se muestra a la mitad y queda por como medio segundo

gracias

JXJ
31-07-2006, 19:31:57
o ¿ alguien que si le haya funcionado ,, algun metodo para
no mostrar el efecto de la animacion al mostrar la ventana hija
y que puede proporcionarlo =?

Gracias

roman
31-07-2006, 20:05:51
Anteriormente había mencionado que quizá funcionaría usando el mensaje WM_SIZE pero no tenía manera de verificarlo en ese momento. Ahora que lo hago veo que no es el mejor lugar. De hecho, según leo en la documentación, WM_SIZE ocurre después de que la ventana cambia de tamaño por lo que es lógio que no funcione.

Según pruebo ahora, puedes intentar con el mensaje WM_SYSCOMMAND:


procedure TForm2.WMSysCommand(var Msg: TWMSysCommand);
begin
if (Msg.CmdType and $FFF0 = SC_MAXIMIZE) or (Msg.CmdType and $FFF0 = SC_RESTORE) then
begin
EnableAnimation(false);
//LockWindowUpdate(Application.MainForm.Handle);

inherited;

//LockWindowUpdate(0);
EnableAnimation(true);
end
else
inherited;
end;


Como ves, he comentado las líneas de LockWindowUpdate pues al inhabilitar la animación, parece que no son necesarias.

// Saludos

JXJ
03-08-2006, 04:09:22
vieras Roman que no me funciona...
se sigue notando la animacion...

sigo probando, con el codigo
para que me funcione a mi tambien.

gracias.

roman
03-08-2006, 05:34:26
Aquí te pongo un ejemplo completo. Mira a ver si tal cual te sirve. Encerré la llamada a SystemParametersInfo en un Assert para asegurarnos que realmente surte efecto pues pudiera ser que por alguna razón no esté inhabilitando la animación.

// Saludos

JXJ
03-08-2006, 23:46:30
Gracias Roman, el efecto de maximizadose reduce, bastante,
solo se nota, un poco al maximizarse.

lo excelente, es que, no me deja con la sensacion, de que
se traba la aplicación, al maximizarse.
y lo noto por que mi pc con el codigo anterior,
como que hacia un ruido de esforzarse más, que con este
reciente codigo