PDA

Ver la Versión Completa : Mi Combo y yo


vichovi
09-06-2003, 13:15:32
Hola a tod@s:

Estoy haciendo un componente (para practicar :p) derivado de TComboBox cuya propiedad importante (y unica) es la propiedad AutoWidth, la cual si esta a verdadero hace que al desplegar la lista del combo se vean todos los elementos.

Si la introduccion de los distintos elementos (Items) es en tiempo de diseño no hay problema, todo radica cuando añado items en tiempo de ejecucion que no se que hacer para que se vuelva a recalcular el ancho de los items. Uso el metodo RePaint pero no hace nada.

A ver si alguien me puede echar una manita (por favor)

Los fuentes del componente los podeis encontrar en:

http://vichovi.en.eresmas.com/ComboBoxSpecial.zip

andres1569
09-06-2003, 14:36:51
Hola:

En tu nuevo componente deberías interceptar cuándo se han añadido, borrado o cambiado elementos de la propiedad Items. Es preferible que esto lo controle el componente, y no hacerlo "manualmente" desde tu programa, llamando a Repaint (este método no es el mejor para esto, puesto que se llama cada vez que se redibuja el control, aunque no esté desplegado).

Puesto que estás de practicas no te voy a ofrecer una solución completa, sólo algunas pistas. La propiedad Items de un Combo es del tipo TComboBoxStrings (todo esto lo puedes ver en la VCL). Cuando se inserta, elimina o cambia un Item, Items envía mensajes del tipo CB_ADDSTRING, CB_DELETESTRING ... etc al ComboBox asociado. Si el ComboBox intercepta estos mensajes, puedes poner a TRUE una variable booleana, llamémosla FItemsChanged, que indique que ha algo cambiado. Luego sobrescribes el método DropDown y ahí recalculas todo si ha habido cambios.

Otra cosa, he visto el codigo del componente. En el método Set de la propiedad Autowidth podrías comprobar en primer lugar que el valor pasado es diferente al valor de la propiedad, para evitar operaciones innecesarias.

Si finalmente lo implementas como he explicado arriba, podrías simplificar ese método Set de forma que pusiera la variable FItemsChanged a TRUE, sin recalcular el ancho de los Items. Esta operación sólo se realizaría en el DropDown, si hace falta.

vichovi
09-06-2003, 20:44:09
Muchas gracias en cuanto tenga un ratito probare lo que me dices (ya decia yo que como lo llevaba no iba demasiado bien :p)

En cuanto a lo de comprabacion que me comentas (para no hacer calculos innecesarios) la tenia pero probando probando la quite.

Muchisimas gracias por las pistas (las pistas sirven para agilizar la mente jeje)

Un saludo

vichovi
12-06-2003, 15:52:16
Tengo otro pequeño problemilla:

Capturo (por ahora) el mensaje CB_ADDSTRING y pongo a true la variable FItemsChanged (para indicar que los items han cambiado), y el problema es que al combo no se añade el nuevo item.

¿Como hago para añadir el nuevo elemento?

Intento hacer:
self.Items.Add(pchar(mensaje.LParam)

Pero me da un error de desbordamiento de pila.

(supongo que es porque al hacer el items.add del combo se vuelve a generar el mensaje CB_ADDSTRING hasta que se desborda la pila)


Gracias por todo.

andres1569
12-06-2003, 16:04:27
Hola:

En el método donde capturas ese mensaje, sólo tienes que añadir (en este caso da igual antes que después de la línea FItemsChanged := TRUE), la sentencia inherited;, así, tal cual. Cuando se está en un método que intercepta mensajes, Delphi llama al anterior manejador de dicho mensaje que encuentre en la jerarquía de clases, de forma que ese manejador ya se encargará de insertar ese nuevo Item, sin más código por tu parte.

Pensando en este tema, hará falta ver cómo capturar los cambios cuando se asignen los Items "de golpe", mediante Assign. Es otra cuestión a solucionar.

vichovi
12-06-2003, 19:12:28
Gracias de nuevo Andres ya estaremos en contacto (cuando me meta con el Assing)

Un saludo.:D