PDA

Ver la Versión Completa : Pérdida de recursos en Delphi5 con ImageList.


rvinfo
23-06-2003, 13:39:36
Saludos a todos.

Hace tiempo que llevo comprobando que los formularios de Delphi5 pierden recursos cuando contienen un ImageList que hereda de un ImageList que hay en otro formulario y en el que se han modificado las imágenes. Es decir.

Formulario A contiene un ImageList.
Formulario B hereda de A y al ImageList le he añadido una imagen. Este formulario pierde recusos.

En este caso, cuando se abre y cierra el formulario, sin modificarse ni el Frm ni el Pas hace la pregunta “Save changes to… ?”. Si se hace esta operación varias veces se puede observar que los recursos del sistema bajan.

Cuando Delphi5 se cierra, todos los recursos perdidos por todos los proyectos vuelven.

Este problema es un mal menor, porque en tiempo de ejecución no se pierden recursos, sólo en tiempo de diseño. Sin embargo, en mi caso el formulario es el principal del programa y este fallo acaba pasando factura.

Si alguien conoce ya este error y sabe cómo solucionarlo, o al menos sabe algún método para que el formulario principal del proyecto no se cree automáticamente cuando abro el proyecto por favor que eche un cable.

¡Gracias!.

andres1569
23-06-2003, 14:19:52
Hola:

No sé si en esto está la razón de la pérdida de recursos que te sucede pero creo que sí:

El TImageList es un componente que almacena las imágenes en un sólo Bitmap, es decir, que coloca las imágenes una detrás de otra consecutivamente, por eso exige que todas tengan el mismo alto y ancho - fíjate que si modificas las propiedades Height y Width automáticamente borra todos las imágenes cargadas -. Esta es una forma de ahorrar recursos, puesto que no es lo mismo consumir 10 bitmaps que 1 sólo. De esta forma, si tengo cargados por ejemplo 10 bitmaps de 16 x 16, en realidad se crea un Bitmap de 160 x 16, y cada vez que se accede a una imagen, se toma la porción del bitmap correspondiente (por ejemplo la 2ª imagen está dibujada en el rectángulo 16, 0, 32, 16; la 3ª imagen está en 32, 0, 48, 16 y así ...).

Por eso no es buena idea que heredes de un formulario con un TImageList y añadas imágenes puesto que si lo haces así, Delphi te creará un nuevo TImageList con todas las imágenes que ya había más la añadida (es decir, un desperdicio de recursos). Date cuenta de que Delphi no añade sólo la imagen añadida sino un Bitmap que las contiene todas más esa. Sería mucho pedir que Delphi guardara sólo la porción añadida, pero como digo lo coloca todo en un mismo bitmap y de ahí al .DFM. Esto lo puedes comprobar mirando el tamaño de los .DFM respectivos, si añades tan sólo una simple imagen de 16 x 16 al TImageList del form heredado, éste crece más de lo esperado.

¿Por qué te pregunta "Save changes"? No lo tengo muy claro, seguramente trata de hacer una sincronización entre forms (al ser heredado uno de otro), y si ve que el TImageList es diferente, comparando el bitmap, regenera ese Bitmap, lo guarda en el .dfm y pide salvar cambios.

Lo recomendable es que tengas todas las imágenes en un sólo TImageList, colocado por ejemplo en un DataModule al que accedan los formularios, y que cada uno use las que necesite.

A la pregunta de cómo hacer que no se cargue el Form principal, Delphi restaura el entorno de desarrollo que había al cerrar el proyecto, si cierras esa unit principal y luego el proyecto, lo normal es que al reabrir dicho proyecto no te cargue ese formulario.

rvinfo
23-06-2003, 16:44:53
Gracias Andrés, eres el mejor.

Confirmas mis sospechas de que la pérdida se producía por la "sincronización" entre los TImageList de los forms, aunque no conocía la causa, que es la que explicas. Lo de tener el TImageList en un datamodule habrá que probarlo, también tengo malas experiencias con los objetos que se colocan en el Datamodule, pues sueles a estar obligado a partir de ese momento a abrir el datamule siempre antes que el .dfm, miraré a ver cómo se toma el TImageList.

Pues sí, la solución para evitar la apertura del formulario principal era muy sencilla, he puesto la opción del "environment" para que guarde el escritorio y así, efectivamente, puedo evitar que se abra cada vez.

Un saludo.