Example: app_one
Pienso que dar un ejemplo sobre crear controles en ejecuci�n, si bien es muy usado, podr�a ser en vano a menos que la aplicaci�n realmente haga algo �til, por lo tanto en esta secci�n voy a comenzar con el desarrolo de un editor de texto y lo iremos desarrollando hasta que alcanzemos un programa �til que soporte abrir, editar y guardar archivos de textos.
El primer paso, el cual es cubierto por esta secci�n, ser� simplemente crear la ventana y el control EDIT que servir� como centro de nuestro programa.
Comenzaremos con el esquelto del c�digo de la aplicaci�n Simple Window, agregaremos un #define para el ID de nuestro control y los siguientes dos manejadores de mensajes en nuestro window procedure:
#define IDC_MAIN_EDIT 101
case WM_CREATE:
{
HFONT hfDefault;
HWND hEdit;
hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "",
WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL,
0, 0, 100, 100, hwnd, (HMENU)IDC_MAIN_EDIT, GetModuleHandle(NULL), NULL);
if(hEdit == NULL)
MessageBox(hwnd, "Could not create edit box.", "Error", MB_OK | MB_ICONERROR);
hfDefault = GetStockObject(DEFAULT_GUI_FONT);
SendMessage(hEdit, WM_SETFONT, (WPARAM)hfDefault, MAKELPARAM(FALSE, 0));
}
break;
case WM_SIZE:
{
HWND hEdit;
RECT rcClient;
GetClientRect(hwnd, &rcClient);
hEdit = GetDlgItem(hwnd, IDC_MAIN_EDIT);
SetWindowPos(hEdit, NULL, 0, 0, rcClient.right, rcClient.bottom, SWP_NOZORDER);
}
break;
CreateWindowEx( ). Pasamos una clase pre-registrada, en este caso la clase del control "EDIT", y obtenemos un control edit est�ndar. Cuando usamos di�logos para crear nuestros controles, b�sicamente estamos escribiendo una lista de controles a crear, tal que, cuando llamamos a DialogBox( ) o CreateDialog( ) el sistema lee la lista de controles en el recurso di�logo y por cada uno llama a CreateWindowEx(
), con la posici�n y estilo con que fueron definidos.
hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "",
WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL,
0, 0, 100, 100, hwnd, (HMENU)IDC_MAIN_EDIT, GetModuleHandle(NULL), NULL);
if(hEdit == NULL)
MessageBox(hwnd, "Could not create edit box.", "Error", MB_OK | MB_ICONERROR);
Puedes ver que esta llamada a CreateWindowEx( ) especifica cierta cantidad de estilos y no es extra�o tener alguno mas, especialmente para los controles comunes los cuales tienen una larga lista de opciones. Los primeros cuatro estilos WS_ deberian ser obvios, estamos creando el control como un hijo de nuestra ventana, queremos que sea visible y tenga barras de desplazamiento vertical y horizontal. Los tres estilos que son espec�ficos de los controles EDIT (ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL)
especifican que el control edit debe poseer m�ltiples lineas de texto y desplazarse autom�ticamente cuando tipeamos mas alla del l�mite inferior de la ventana y del limite derecho de la misma.
Los estilos regulares (WS_*) puedes encontrarlos en:
listed here.
y los estilos extendidos (WS_EX_*) son explicados en:
CreateWindowEx()
estas referencias son de MSDN donde tambi�n puedes encontrar links a los estilos espec�ficos de cada control (ES_* en el caso del control EDIT).
Hemos especificado nuestro window handle como padre del control y le asignamos un ID de IDC_MAIN_EDIT, el cual usaremos luego para referirnos al control, de la misma manera que lo hariamos si el control hubiera sido creado en un di�logo. Los par�metros de posici�n y tama�o no importan mucho por el momento, debido a que cambiaremos el tama�o del control din�micamente con el mensaje WM_SIZE para que �ste siempre entre en nuestra ventana.
Cambio del tama�o de controles creados din�micamente
Generalmente, si el tama�o de nuestra ventana puede ser cambiado, tendremos alg�n c�digo para reposicionar o ajustar el tama�o de los controles que hemos creado dentro de ella, para que siempre sean mostrados apropiadamente.
GetClientRect(hwnd, &rcClient);
hEdit = GetDlgItem(hwnd, IDC_MAIN_EDIT);
SetWindowPos(hEdit, NULL, 0, 0, rcClient.right, rcClient.bottom, SWP_NOZORDER);
Debido a que por ahora solo tenemos un control, la tarea es relativamente simple. Usamos GetClientRect( ) para obtener las dimensiones del Area Cliente de la ventana, la gran �rea vac�a (por ahora) que no inlcluye los bordes, men� o t�tulo. Esto llenar� nuestra estructura RECT con valores. Los valores left y top siempre ser�n 0, por lo tanto puedes ignorarlos. Los valores right and bottom indican el ancho y el alto del area cliente.
A Continuaci�n, simplemente obtenemos el handle a nuestro control EDIT usando GetDlgItem( ), el cual funciona bien en las ventanas regulares como en los di�logos y la llamada SetWindowPos( ) para mover y ajustar el tama�o para llenar todo el �rea cliente. Por su puesto, puedes cambiar los valores pasados en SetWindowPos( ) para hacer algo como s�lo llenar la mitad del alto de la ventana, dejando libre la parte inferior para ubicar otros controles.
Crear otros controles en tiempo de ejecuci�n
No voy a dar ejemplos de como crear din�micamente los otros controles, como listas, botones, etc... debido a que es b�sicamente lo mismo. Si visitas los links anteriores en MSDN o buscas en tu referencia de Win32 API, encotrar�s toda la informaci�n necesaria para crear cualquiera de los otros controles est�ndar.
Veremos mas sobre esto con los controles comunes, en la siguientes secciones, donde obtendr�s mas pr�ctica.
Copyright © 1998-2003, Brook Miles (theForger). All rights reserved.
Versi�n en Espa�ol: Federico Pizarro - 2003