[C con Clase] Insertar datos ListView

Steven Davidson srd4121 en njit.edu
Jue Mayo 15 10:45:57 CEST 2008


Hola Fernando,

Fernando wrote:
> Hola Steven, tengo un ListView y deseo insertar (filas) datos desde
> un button cada vez q lo presionó, tome código (listview) de un
> mensaje q dirijias a otra persona anteriormente, el detalle es q
> cuando inserto las filas línea por línea si lo hace bien, pero cuando
> lo hago a través de ciclos nomás no puedo, parte del siguiente código
> lo escribí en mi procedimiento de dialogo:
> 
>     int iCol=0, iCont=0;
>     
>     static char *pcElemListView[4][6]=
>     {
>         {"5","KG","0001","HUEVO ROJO","12.00","65.00"},
>         {"10","CN","0005","CONO VACIO",".50","5.00"},
>         {"2","KG","0002","HUEVO BLANCO","13.00","26.00"},
>         {"7","CJ","0006","LECHE LALA LIGHT","10.50","73.50"},
>     };
> 
>     while(iCont<1)
>     {
>         liEle.mask = LVIF_TEXT;
>         liEle.iItem = iFil ;
>         while(iCol<6)
>         {
>             liEle.iSubItem = iCol;
>             liEle.pszText= pcElemListView[iFil][iCol];
>             liEle.cchTextMax = strlen(pcElemListView[iFil][iCol]);
>             if(iCol==0) ListView_InsertItem(hNtaOper, &liEle);
>             else ListView_SetItem(hNtaOper, &liEle);
>             iCol++;
>         }   
>         iFil++; iCont++;
>     }
>     ListView_SetExtendedListViewStyle(hNtaOper, LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_HEADERDRAGDROP);
> 
> El resultado es q en 2 filas sólo me muestra el dato de una columna,

El error está en tu primer bucle 'while'. Éste se basa en el valor en 
'iCont', cuando la verdad es que debería basarse en 'iFil'. Además, el 
valor a la derecha de < es 1, lo cual implica que este bucle se 
realizará una sola vez, ya que inicialmente iCont = 0.

El otro error es que no reinicias el valor de 'iCol' a 0 (cero) para el 
segundo bucle 'while' anidado.

Para eliminar peligros de este tipo, sugiero usar bucles 'for' para este 
código. Esto es,

for( iFil=0; iFil < 4; iFil++ )
{
   ...
   for( iCol=0; iCol < 6; iCol++ )
   {
     ...
   }
}

> y ya para finalizar, es posible desactivar es estilo de las columnas
> p que no se cambie su tamaño con el mouse, pues requiero se mantengan
> con la longitud q ya tienen.

Tendríamos que programar el control de cabecera que pertenece al control 
del listado con vistas (listview). Para esto, podemos usar la macro 
'ListView_GetHeader()' para obtener el manipulador del control de cabecera.

La idea es procesar el mensaje de notificación 'HDN_BEGINTRACK' nosotros 
mismos. El problema es que este mensaje lo envía el control de cabecera 
al control "listview" internamente, pero nosotros estamos programando el 
cuadro de diálogo. En otras palabras, no tenemos un acceso directo a tal 
procedimiento.

Existen tres posibles soluciones:
1. Realizar una subclase del control de cabecera. Esto significa que 
sustituiremos su procedimiento de ventana por el nuestro. Así podemos 
modificar el comportamiento a nuestro gusto.

2. Realizar una subclase del control "listview". Cuando este control 
reciba el mensaje de notificación 'HDN_BEGINTRACK', podemos procesarlo a 
nuestra manera: ignorarlo.

3. Cambiar la ventana pariente del control de cabecera invocando 
'SetParent()'. En lugar de ser el control "listview", indicaremos 
nuestro cuadro de diálogo. Esto supondrá que nuestro cuadro de diálogo 
recibirá mensajes de notificación del control de cabecera; así podemos 
descartar este mensaje. Para los demás mensajes los podemos enviar al 
control "listview".

También aconsejo impedir cambiar el cursor para que los usuarios no se 
confundan. Pueden pensar que se puede cambiar la anchura, pero luego el 
programa no les deja hacerlo. Usa 'SetCursor()' para indicar el cursor 
que quieres.

> "Mil gracias por compartir tu tiempo y experiencia con los novells..."
> 

De nada; para eso estamos.


Espero que lo anterior te ayude.

Steven






Más información sobre la lista de distribución Cconclase