Apunte de Visual C++
Por: Demian Panello demianpanello@yahoo.com.ar
Capítulo IV
Indice rápido del capítulo 4:
Las listas son otros de los objetos más importantes en Windows. Existen: listas, listas desplegables, lista de archivos, listas de directorios, etc. Todas funciones y características propias pero funcionan básicamente igual. Veamos un ejemplo.
- Cree un nuevo proyecto basado en diálogos con el MFC AppWizard y llámelo listas1.
Coloque 2 controles ListBox un al lado del otro y dos botones entre ellos.


El objetivo del programa será hacer uso de diferentes eventos y propiedades de las listas.
Se ingresará un valor numérico mayor a 0 en el cuadro de edición, luego se presionará el botón Cargar y se cargará la lista IDC_NUMEROS con los números naturales menores al contenido del cuadro de edición.
También será posible seleccionar un elemento de la lista y mostrarlo en un mensaje.
Al presionar el botón >> se pasarán todos los valores pares de IDC_NUMEROS a IDC_PARES y presionando > , se pasará el valor seleccionado siempre y cuando sea par.
Finalmente presionando Aceptar se terminará la aplicación, pero antes preguntando al usuario si es realmente lo que desea.
Primero codificaremos el botón Aceptar; haciendo doble click vamos directamente al mensaje por dedfecto OnOk(), ahí escriba:
void CListas1Dlg::OnOK()
{
// TODO: Add extra validation here
if (MessageBox("¿Desea salir?","Salir",MB_ICONQUESTION+MB_YESNO)==IDYES)
CDialog::OnOK();
}
Lo único que se agregó fue la línea if, donde se averigua que botón del MessageBox se ha pulsado; si fue YES se termina el programa, caso contrario continúa todo igual.
En este caso se hace uso del valor que retorna MessageBox(), que pueden ser varios de acuerdo a los botones usados en el mensaje.
Si probamos la aplicación y pulsamos el botón Aceptar veremos que ahora aparece un mensaje preguntando si efectivamente queremos salir; mensaje típico de todo programa Windows.
Seleccione el botón Cargar y acceda a ClassWizard. Allí seleccione Message Maps, luego en Objects ID’s marque IDC_CARGAR, en MESSAGE marque BN_CLICKED y entonces presione ADD FUNCTION e inmediatamente EDIT CODE.
Aparecerá la función OnCargar(), allí escriba:
void CListas1Dlg::OnCargar()
{
// TODO: Add your control notification handler code here
CString c; (1)
int i; (2)
UpdateData(TRUE); (3)
m_lstNumeros.ResetContent (); (4)
for (i=1; i<=m_Cant; i++) (5)
{
c.Format ("%s%i",c, i); (6) //formateo i como String
m_lstNumeros.AddString(c); (7) //lo agrego a la lista
c="";
}
}
El contenido de una lista es de tipo Cstring, por eso se declara una variable de este tipo en (1), luego en (2) se declara un valor entero para recorrer todos los valores menores al ingresado en el cuadro de edición.
Con UpdateData(TRUE) en (3) se transfiere el contenido del cuadro de edición a la variable miembro m_Cant.
En (4) se limpia el contenido de la lista; y en (5) se realiza un bucle variar para i =1 hasta m_Cant, lo que da a lugar que por cada vuelta el elemento que debemos cargar en la lista es el índice i pero convertido ha cadena, que es lo que hace (6) con la función Format de la clase CString dejando el valor formateado en la variable c que en (7) es agregada a la lista con la función AddString de la clase CListBox.
Ya tenemos cargada la lista IDC_NUMEROS, ahora vamos a escribir el código que al seleccionar un elemento lo muestre en un mensaje.
Para esto seleccionamos la lista y accedemos a ClassWizard, allí en Message Maps con IDC_NUMEROS marcado en Object ID’s seleccionamos LBN_SELCHANGE en Message, pulsamos Add Function y luego Edit Code.
Escriba:
void CListas1Dlg::OnSelchangeNumeros()
{
// TODO: Add your control notification handler code here
CString strTexto; (1)
m_cboNumeros.GetText (m_cboNumeros.GetCurSel (), strTexto); (2)
MessageBox(strTexto); (3)
}
El elemento seleccionado si bien es un número porque precisamente cargamos números son de tipo CString, o sea cadenas, por eso se declara en (1) la variable CString strTexto.
Los elementos de una lista se encuentran dentro de ella en una posición determinado empezando por el primero que se ubica en posición 0 el segundo en 1 así sucesivamente. La función GetCurSel() retorna la ubicación de el elemento seleccionado, o sea si está marcado el primero retorna 0; y GetText() que tiene 2 parámetros (ubicación, contenido), deja en el segundo parámetro el valor ubicado en lo indicado en el primer parámetro; por eso en (2) se usa esa combinación de funciones: obtener el texto del seleccionado y dejarlo en la variable strTexto.
En la línea (3) se muestra el elemento seleccionado.
Escribiremos ahora el código para el botón IDC_PASAPARES.
Cree la función OnPasapares(), a través de ClassWizard o simplemente haciendo doble click en el control.
void CListas1Dlg::OnPasapares()
{
// TODO: Add your control notification handler code here
int i, n, ce; (1)
CString strC; (2)
ce=m_lstNumeros.GetCount (); (3)
if (ce > 0) (4)
for (i=0; i< ce; i++) (5)
{
m_lstNumeros.GetText (i, strC); (6) //obtengo elemento
n=atoi(strC); (7) //lo convierto a numérico
if(n%2==0) (8) //averiguo si es par
m_lstPares.AddString(strC); (9) //lo paso a la otra
}
}
Primero (1) se declaran variables enteras; i será el índice del variar, ce la cantidad de elementos de la lista IDC_NUMEROS y n donde se almacenará cada elemento convertido a numérico para poder averiguar si es par o no. En strC se almacenará cada elemento.
En (3) por medio de GetCount() se obtiene la cantidad de elementos en IDC_NUMEROS.
Si la cantidad de elementos es mayor a 0 (4) comienzan a recorrerse todos los elementos de la lista, desde el primero, 0, hasta el último, ce-1. Por cada elemento obtengo el contenido a través de la función GetText (5) a la cual se le pasa el índice i y la variable donde dejará el valor.
Como tengo que ver si ese valor es par o no, debo pasarlo a entero, pues es una cadena; esto hace la línea (7) por medio de la función atoi (array to integer), dejando en la variable n el valor en formato integer.
Si el resto de dividir n por 2 es 0, es porque es par, entonces, lo paso a IDC_PARES, así sucesivamente, elemento por elemento hasta recorrer toda la lista IDC_NUMEROS.
El botón IDC_PASA1 es más fácil, pues solamente hay que averiguar si es par el que está seleccionado.
Cree una función de gestión para el mensaje OnPasa1, tal como lo hizo para el botón anterior, y escriba:
void CListas1Dlg::OnPasa1()
{
// TODO: Add your control notification handler code here
int n;
CString strC;
m_lstNumeros.GetText (m_lstNumeros.GetCurSel (), strC);
n=atoi(strC);
if (n%2==0)
m_lstPares.AddString (strC);
}
Estas líneas de código son exactamente las misma que están en el botón IDC_PASAPARES, (detalladas anteriormente), sólo que aquí no hace falta ningún bucle pues solamente interesa el elemento seleccionado.
Se obtiene el valor del elemento seleccionado, se lo convierte a entero, se averigua si es par y en caso positivo se lo pasa a la otra lista.
Resumiendo: