[C con Clase] como passo un array de estructuras a un cuadro de dialogo?
Steven Davidson
steven en conclase.net
Lun Ene 8 09:46:06 CET 2007
Hola Francesc,
El pasado 2007-01-07 10:41:44, borubudur escribió:
b> hola de nuevo,
b> parece que el método universal para pasar información entre el procedimiento principal y un cuadro de dialogo es mediante una estrucutra, por ejemplo
b> typedef struct stDatos {
b> char Nombre[80];
b> int edad;
b> } DATOS;
b> claro que con esta estructura sólo hay capacidad para una persona, por lo tanto mas adelante defino
b> DATOS datos[100];
b> así ya tengo sitio para 100 personas, pero si pretendo comunicarme con un cuadro de dialogo tocaria usar.....
b> DialogBoxParam(hInst, "INFORMACIÓN", hwnd, DlgProc, (LPARAM)&Datos);
Hasta aquí, vamos por buen camino.
b> para activar el control
b> y para rellenar los datos en el control (listbox, etc..)
b> for (a=0;a<10;a++)SendDlgItemMessage(hDlg,ID_LISTA,LB_ADDSTRING,0,(LPARAM);Datos[a]->Nom);
b> lo que pasa es que Datos[a] no es correcto;
b> me pregunto si la solució pasa por declarar
b> DATOS *datos
b> pero entonces me da la sensación que algo va a ir mal por otro sitio
Podrías declarar un puntero en lugar de un array, pero entonces tocaría crear memoria dinámicamente. Si sabes que vas a usar 100 estructuras, entonces sigue usando un array (estático).
Ahora bien, el bucle es incorrecto. Escribes:
for (a=0;a<10;a++)
SendDlgItemMessage(hDlg,ID_LISTA,LB_ADDSTRING,0,(LPARAM);Datos[a]->Nom);
Al tratarse de 100 estructuras, supongo que en este caso, la cabecera del bucle debería ser:
for( a=0; a<100; a++ )
En cuanto al uso de 'Datos', tienes que tener en cuenta que el procedimiento del diálogo acepta un valor de tipo 'LPARAM'. Por lo tanto, debemos cambiar su tipo a la hora de usar tal valor; o sea, necesitamos hacer un cásting. Esto es,
BOOL CALLBACK DlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam )
{
switch( msg )
{
case WM_INITDIALOG:
for( a=0; a<100; a++ )
SendDlgItemMessage( hDlg, ID_LISTA, LB_ADDSTRING, 0,
(LPARAM) (((DATOS *)lParam)[a]->Nom) );
return TRUE;
}
...
}
Lo que hacemos es realizar un cásting a 'lParam' para que vuelva a ser el tipo 'DATOS *' para poder operar con tal valor. Luego el valor de la expresión pasa a ser un 'LPARAM', para no tener complicaciones con la concordancia de tipos.
Como puedes ver, lo anterior es algo engorroso con tantos cástings y paréntesis. Además, tendrías que hacer algo parecido cada vez que quieras usar el array de estructuras. Por lo tanto, sugiero crear un puntero estático y local al procedimiento del diálogo, para que no tengas que estar haciendo tantos cástings. Esto sería,
BOOL CALLBACK DlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam )
{
static DATOS *Datos;
switch( msg )
{
case WM_INITDIALOG:
Datos = (DATOS *) lParam;
for( a=0; a<100; a++ )
SendDlgItemMessage( hDlg, ID_LISTA, LB_ADDSTRING, 0,
(LPARAM) (Datos[a]->Nom) );
return TRUE;
}
...
}
Ahora podemos usar 'Datos' donde queramos, dentro de 'DlgProc()'.
Espero que haya aclarado la duda.
Steven
Más información sobre la lista de distribución Cconclase