4 El procedimiento de ventana

Cada ventana tiene una función asociada, esta función se conoce como procedimiento de ventana, y es la encargada de procesar adecuadamente todos los mensajes enviados a una determinada clase de ventana. Es la responsable de todo lo relativo al aspecto y al comportamiento de una ventana.

Normalmente, estas funciones están basadas en una estructura "switch" donde cada "case" corresponde aun determinado tipo de mensaje.

Sintaxis

LRESULT CALLBACK WindowProcedure(
   HWND hwnd,     // Manipulador de ventana
   UINT msg,      // Mensaje
   WPARAM wParam, // Parámetro palabra, varía
   LPARAM lParam  // Parámetro doble palabra, varía
  );
  • hwnd es el manipulador de la ventana a la que está destinado el mensaje.
  • msg es el código del mensaje.
  • wParam es el parámetro de tipo palabra asociado al mensaje.
  • lParam es el parámetro de tipo doble palabra asociado al mensaje.

Podemos considerar este prototipo como una plantilla para crear nuestros propios procedimientos de ventana. El nombre de la función puede cambiar, pero el valor de retorno y los parámetros deben ser los mismos. El miembro lpfnWndProc de la estructura WNDCLASS es un puntero a una función de este tipo, esa función es la que se encargará de procesar todos los mensajes para esa clase de ventana. Cuando registremos nuestra clase de ventana, tendremos que asignar a ese miembro el puntero a nuestro procedimiento de ventana.

Para más detalles sobre la función de procedimiento de ventana, consultar WindowProc.

Prototipo de procedimiento de ventana

LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM);

Implementación de procedimiento de ventana simple

/* Esta función es llamada por la función del API DispatchMessage() */
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)                  /* manipulador del mensaje */
    {
        case WM_DESTROY:
           PostQuitMessage(0);    /* envía un mensaje WM_QUIT a la cola de mensajes */
           break;
        default:                  /* para los mensajes de los que no nos ocupamos */
           return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

En general, habrá tantos procedimientos de ventana como programas diferentes y todos serán distintos, pero también tendrán algo en común: todos ellos procesarán los mensajes que lleguen a una clase de ventana.

En este ejemplo sólo procesamos un tipo de mensaje, se trata de WM_DESTROY que es el mensaje que se envía a una ventana cuando se recibe un comando de cerrar, ya sea por menú o mediante el icono de aspa en la esquina superior derecha de la ventana.

Este mensaje sólo sirve para informar a la aplicación de que el usuario tiene la intención de abandonar la aplicación, y le da una oportunidad de dejar las cosas en su sitio: cerrar ficheros, liberar memoria, guardar variables, etc. Incluso, la aplicación puede decidir que aún no es el momento adecuado para abandonar la aplicación. En el caso del ejemplo, efectivamente cierra la aplicación, y lo hace enviándole un mensaje WM_QUIT, mediante la función PostQuitMessage.

El resto de los mensajes se procesan en el caso "default", y simplemente se cede su tratamiento a la función del API que hace el proceso por defecto para cada mensaje, DefWindowProc.

Este es el camino que sigue el mensaje WM_QUIT cuando llega, ya que el proceso por defecto para este mensaje es cerrar la aplicación.

En posteriores capítulos veremos como se complica paulatinamente esta función, añadiendo más y más mensajes.

Primer ejemplo de programa Windows

Ya estamos en condiciones de crear nuestro primer programa Windows, que sólo mostrará una ventana en pantalla.

Nombre Fichero Fecha Tamaño Contador Descarga
Ejemplo 1 win001.zip 2004-01-18 1937 bytes 1023