Está en la página 1de 2

[ contenidos | #winprog ]

Aplicación Parte 1: Crear Controles en Tiempo de Ejecución


Example: app_one
[images/app_one.gif]
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;
Crear los controles
Para crear los controles, al igual que lo hacemos para cualquier otra ventana,
utilizamos la API 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

También podría gustarte