[ contenidos | #winprog ]

Diálogos FAQ

Ejemplo: dlg_three

[images/dlg_three.gif]

No confundan, esto es un Tutorial, no una Referencia, pero las preguntas de algunas personas son tan frecuentes que he pensado que sería bueno incluirlas aqui.

Cambio de los colores

En general la única razón por la cual querrías hacer esto debe ser para simular un link en un diálogo o alguna tarea similar, porque en otro caso estarías haciendo que tu programa luzca horroroso a la vista si agregas una gran cantidad de colores a los diálogos. De todas maneras esto no impide a las personas de hacerlo y hay algunas razones válidas, aquí van :)

Windows envía a nuestro dialog procedure una gran cantidad de mensajes relacionados a los colores y procesando dichos mensajes podemos cambiar el color de ciertas cosas. Por ejemplo para cambiar el color de el diálogo en si mismo podemos procesar el mensaje WM_CTLCOLORDLG, para cambiar el color de un control estático podemos procesar el mensaje WM_CTLCOLORSTATIC, etc...

Primero debemos crear un pincel (Brush) para pintar el fondo y luego almacenarlo para poder usarlo después. El mensaje WM_CTLCOLORDLG y otros mensajes relacionados serán llamados aún durante el trancurso de la ejecución de nuestro programa y si cada vez que esto sucede creamos un pincel podriamos desperdiciar una gran cantidad de RAM con pinceles muertos. De esta forma tenemos mas control y podemos borrarlo cuando el diálogo es destruído, es decir, cuando ya sabemos que no lo vamos a necesitar mas.

    HBRUSH g_hbrBackground = CreateSolidBrush(RGB(0, 0, 0));
    case WM_CTLCOLORDLG:
        return (LONG)g_hbrBackground;
    case WM_CTLCOLORSTATIC:
    {
        HDC hdcStatic = (HDC)wParam;
        SetTextColor(hdcStatic, RGB(255, 255, 255));
        SetBkMode(hdcStatic, TRANSPARENT);
        return (LONG)g_hbrBackground;
    }
    break;

Observa la línea que fija el color de fondo en modo transparente... si quitamos esta linea el fondo será llenado con el pincel que hemos especificado, pero cuando el control dibuje el texto, éste será escrito encima con el color de fondo por default! Poniendo el modo de dibujo de texto en transparente corregimos este problema. La otra opción sería usar SetBkColor( ) para poner como color de fondo el mismo color del pincel, pero prefiero la otra solución.

Cambiar los colores en la mayoria de los controles estándar funciona de la misma manera, solo hay que observar los mensajes WM_CTLCOLOR* en la referencia de Win32. Observa que un control Edit enviará un mensaje WM_CTLCOLORSTATIC si es de solo lectura y WM_CTLCOLOREDIT si no lo es.

Si tienes mas de un control estático y quieres que tengan diferentes colores, entonces cuando procesas los mensajes, necesitarás chequear el ID del control que envía el mensaje para identificar de que control proviene y asi cambiar los colores al control adecuado. Tenemos el HWND del control en lParam y a partir de este podemos obtener el ID del control usando GetDlgCtrlID( ). Observa que el editor de recursos les da a los controles estáticos un ID IDC_STATIC igual a -1, por lo tanto si necesitamos distinguirlos debemos asignarles nuevos IDs.

Poner un ícono en el Diálogo

Es una tarea simple, solo necesitamos enviar a nuestro diálogo el mensaje WM_SETICON. Sin embargo, debido a que Windows utiliza dos íconos, necesitamos enviar el mensaje dos veces: una vez para el ícono pequeño mostrado en la esquina de la ventana y otra vez para el ícono grande mostrado cuando presionamos Alt+Tab. Podemos enviar el mismo handle ambas veces, a menos que tengamos iconos de diferentes tamaños.

Para poner el icono de aplicación por default, podemos usar el siguiente código:

    SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(NULL, MAKEINTRESOURCE(IDI_APPLICATION)));
    SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)LoadIcon(NULL, MAKEINTRESOURCE(IDI_APPLICATION)));

Cuando reemplazes tu propio ícono por uno por default, recuerda cambiar el parámetro HINSTANCE de LoadIcon( ) por el de la instancia de tu aplicación (si no lo tienes almacenado en WinMain( ), puedes obtener éste llamando a GetModuleHandle( )).

¿Por que no funciona mi Combo Box?

Uno de los problemas mas comunes que las personas tienen cuando agregan un Combo Box a sus dialogos es que no pueden darse cuenta por qué la lista no puede ser mostrada cuando corren sus programas y hacen click en la flecha pequeña. Esto es entendible, debido a que la solución no es muy intuitiva.

Cuando creamos un combo box y especificamos su altura, estamos especificando la altura entera, con la lista despelegada incluida, NO la altura del control cuando no está desplegado, ya que ésta es determinada por el sistema de acuerdo al tamaño de la fuente usada.

Por ejemplo, si le damos al control una altura de 100 pixeles, el sistema ajusta el tamaño del control con un valor por default (digamos 30 en este caso) y cuando hacemos click en la flecha la lista desplegada podría ser de una máximo de 70 pixeles, haciendo un total de 100 pixeles.

Si utilizas el editor de recursos de VC++ para ubicar el combo box dentro de tu dialogo, observarás que no puedes cambiar el tamaño vertical. A menos que hagas click en la flecha en el editor y éste cambiará el foco para indicar que estás cambiando el tamaño de la lista desplegada. Luego puedes especificar el ancho con el valor que quieras.

¿Que pasa con todos los otros controles?

Bien, podría dar ejemplo de todos los otros controles, pero es lo que hacen MSDN y Petzold :) Si no puedes darte cuenta de como usarlos, probablemente necesites re-leer algunas partes de este tutorial, o conseguir un libro que explique las cosas mas ampliamente.

Quiero darte un link a una página muy buena en MSDN, pero Microsoft parece estar determinado a impedirme dar links a páginas individuales, debido a que cambian rápidamente o no funcionan por un período. Por lo tanto tendrás que darte cuenta como llegar vos mismo, busca las secciones como User Interface Services y Windows Controls, a veces dentro de la sección Plataform

MSDN - Windows Controls


Copyright © 1998-2003, Brook Miles (theForger). All rights reserved.

Vesrsión en Español: Federico Pizarro