[C con Clase] Preguntas

sebastianoldani sebastianoldani en gmail.com
Dom Jun 24 19:29:18 CEST 2007


Muchas Gracias Steven, muy claro, voy a practicar con todo esto, muy 
claros los ejemplos y gracias por los tips.
Nos vemos.


Steven Davidson escribió:
> Hola Sebastián,
>
> El pasado 2007-06-23 21:24:10, sebastian escribió:
>
> s> Hola, escribo denuevo, estoy tratando de entender la logica de programar 
> s> sin las comodidades de los ide y se me esta complicando un poco, 
> s> obiamente hay muchicimas cosas que no entiendo, asi qeu necesitaria que 
> s> alguien me aclare un poco el panorama porque la verdad que me estoy 
> s> complicando demaciado, las cosas que no entiendo son las siguiente:
>
> A ver las dudas.
>
> s> 1) Cuando creo un control, primero declaro:
> s> static HWND hwndButton; //Que significa que sea static, porque sino lo 
> s> pongo funciona igual, es mas en muchos ejemplos lo vi asi y en otros sin 
> s> static.
>
> Esta pregunta tiene que ver con C/C++ que con buenas prácticas de la programación. El modificador 'static' sirve para declarar una variable estática. Esto depende del ámbito en que estemos. Si declaramos una variable local estática, entonces esta variable no es destruida al finalizar el ámbito. Por ejemplo,
>
> int func()
> {
>   static int nContador=0;
>
>   return nContador++;
> }
>
> int main()
> {
>   cout << func() << endl;
>   cout << func() << endl;
>   cout << func() << endl;
>   cout << func() << endl;
>   cout << func() << endl;
>
>   return 0;
> }
>
> Aparecerá en pantalla:
> 0
> 1
> 2
> 3
> 4
>
> Recuerda que las variables locales son creadas y destruidas al entrar y salir, respectivamente de tal ámbito. Con 'static', indicamos que la variable permanecerá existiendo aun haberse terminado su ámbito.
>
> En los programas con el API de MS-Windows, típicamente declaramos las variables locales al procedimiento de ventana como estáticas. Por ejemplo,
>
> LRESULT CALLBACK WinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
> {
>   static HWND hAceptar, hValoresPreestablecidos;  // Botones
>   static HWND hInfo;  // ComboBox
>
>   switch( msg )
>   {
>     case WM_CREATE:
>       hAceptar = CreateWindowEx( ... );
>       hValoresPreestablecidos = CreateWindowEx( ... );
>       hInfo = CreateWindowEx( ... );
>     return 0;
>     ...
>   }
>
>   return DefWindowProc( hwnd, msg, wParam, lParam );
> }
>
> Ten presente que 'WinProc()' es una función que será invocada muchísimas veces a lo largo de la ejecución de nuestra aplicación. Si no declaráramos estas variables como estáticas, perderíamos sus valores al finalizar la función, ya que las variables locales son destruidas automáticamente.
>
> Si no nos interesa guardar la información en las variables locales, entonces no usamos 'static'. Lo más seguro es que sí nos interesa mantener tal variable, pero esto ya depende de cada aplicación y su diseño.
>
> s> 2) Tengo que declarar todos los controles con un HWND nombre distinto? 
> s> eso seria lo correcto?, porque tambien vi ejemplos en los uqe todos los 
> s> contros tienen el mismo y en otros todos se llaman distinto, funciona de 
> s> las 2 maneras y se los puede diferenciar desde el ID.
>
> Efectivamente, podemos usar el número de identificación del control en lugar del manipulador de ventana. Si esto es así, entonces no nos interesa guardar tal manipulador. En la práctica, creo que es mejor mantener el manipulador si tienes intención de enviar muchos mensajes al control, seguramente para inicializarlo. Ahora bien, si tienes que invocar varias funciones que requieren el manipulador para poder invocarlas, entonces sí aconsejo mantener el manipulador del control. Por ejemplo,
>
> LRESULT CALLBACK WinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
> {
>   static HWND hAceptar, hValoresPreestablecidos;  // Botones
>   static HWND hInfo;  // ComboBox
>   static HBRUSH hPincelFondo;
>
>   switch( msg )
>   {
>     case WM_CREATE:
>       hPincelFondo = CreateSolidBrush( RGB(110,145,0) );  // Color aceituno
>       hAceptar = CreateWindowEx( ... );
>       hValoresPreestablecidos = CreateWindowEx( ... );
>       hInfo = CreateWindowEx( ... );
>     return 0;
>
>     case WM_CTLCOLORBTN:
>     if( (HWND) lParam == hAceptar )  // Sólo para el botón "Aceptar"
>       return (LRESULT) hPincelFondo;
>     break;
>
>     case WM_DESTROY:
>       DeleteObject( hPincelFondo );
>       PostQuitMessage( 0 );
>     return 0;
>     ...
>   }
>
>   return DefWindowProc( hwnd, msg, wParam, lParam );
> }
>
> s> 3) Supongamos que tengo un boton que suma un contador, y que tengo otro 
> s> que muestra el valor que tiene, como se podria hacer para que un 3er 
> s> boton haga las dos acciones sin tener que declarar todo lo que tiene 
> s> cada uno de los botones en su evento. Como qeu pueda poner que cuando 
> s> hago clic en ese boton haga el evento de otro boton y despues el de otro 
> s> (Es un ejemplo simbolico para que se entienda mejor la pregunta).
>
> Tienes dos formas de solucionar este problema:
> 1. Crea funciones para incluir las mismas tareas. Así, cada componente interactivo - control u otro mecanismo - realiza la misma tarea con tan sólo invocar la misma función.
>
> 2. Simular el mismo efecto "engañando" al sistema o enviando un mensaje específico.
>
> Por ejemplo,
>
> LRESULT CALLBACK WinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
> {
>   static HWND hSumar, hMostrar, hSumarMostrar;
>   ...
>   case WM_COMMAND:
>     if( (HWND) lParam == hSumar )
>     {
>       // Sumar el contador
>       Sumar();
>     }
>     else if( (HWND) lParam == hMostrar )
>     {
>       // Mostrar el contador
>       Mostrar();
>     }
>     else if( (HWND) lParam == hSumarMostrar )
>     {
>       // Sumar y Mostrar el contador
>       SendMessage( hwnd, WM_COMMAND,
>           MAKEWPARAM( LOWORD(wParam), (WORD) IDC_SUMAR ), (LPARAM) hSumar );
>       SendMessage( hwnd, WM_COMMAND,
>           MAKEWPARAM( LOWORD(wParam), (WORD) IDC_MOSTRAR ), (LPARAM) hMostrar );
>
>       // Usando nuestras propias funciones:
>       // Sumar();
>       // Mostrar();
>     }
>   break;
>   ...
> }
>
> Dependiendo de los controles que tengas o mejor dicho de los diversos mecanismos interactivos implementados, te convendrá aplicar una técnica u otra.
>
> s> Bueno, todas mis preguntas estan orientadas a tener el mejor 
> s> funcionamiento de la aplicacion, para poder escribir el codigo lo mas 
> s> correcto posible.
> s> Algunas de las cosas que pregunto funcionan de varias formas, pero 
> s> quiero saber cual es la forma mas correcta.
>
> Hasta cierto punto depende de lo que te guste manejar: el manipulador de la ventana hija o su ID. Por motivos de emplear una estrategia, es mejor usar números de identificación. Por ejemplo, si tenemos 20 controles del mismo tipo que interactivamente se agrupan y tienen relación con algún array, entonces es mejor planificar unos números consecutivos. Con esta estrategia podemos comunicarnos fácilmente con la información del array, ya que sus índices también son consecutivos. Por ejemplo,
>
> const int IDC_BOTONES = 100;
>
> infoT info[50];
> ...
> for( int i=0; i<50; i++ )
> {
>   CreateWindowEx( 0L, "BUTTON", ..., (HMENU) (IDC_BOTONES+i), ... );
>   ...
> }
>
> Ahora tenemos que los controles quedan asociados a los elementos en el array 'info'. Por ejemplo,
>
> WM_COMMAND:
>   if( HIWORD(wParam) == BN_CLICKED )
>   {
>     WORD nID = LOWORD( wParam );
>     if( IDC_BOTONES <= nID&&nID <= IDC_BOTONES+50 )
>       SendMessage( hEdicion, WM_SETTEXT,
>                    0, (LPARAM)(info[nID-IDC_BOTONES].texto) );
>   }
> return 0;
>
> Esta técnica o estrategia es parecida a la que se suele emplear para los elementos de un menú.
>
>
> Espero que esto te aclare las dudas.
>
> Steven
> _______________________________________________
> Lista de correo Cconclase Cconclase en listas.conclase.net
> http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
> Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ
>
>   





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