Typedefs en Windows:
§1 Sinopsis
Los typedef son de utilización muy común, ya que en muchas ocasiones suponen una economía y simplificación en la notación. Sin embargo, como hemos señalado ( 3.2.1a), una de las razones de su uso, y quizás la más importante, es que permite concentrar en un solo punto del código determinadas referencias, lo que resulta decisivo para la portabilidad de aplicaciones entre distintas plataformas. Este es precisamente el caso de las aplicaciones escritas para la API de Windows, donde se utilizan con profusión estos nombres alternativos. Su uso permite a los desarrolladores despreocuparse de determinadas cuestiones de detalle, y utilizar los mismos identificadores en sus aplicaciones, con independencia de que estas puedan ser posteriormente compiladas para versiones Windows de 16, 32 o 64 bits. Por ejemplo, la aplicación puede utilizar un tipo UINT en todas las funciones que devuelven dicho tipo, con independencia de como sea interpretado finalmente por el compilador. Este detalle será encomendado a los ficheros de cabecera, que pueden contener distintas definiciones de este typedef para cada compilador concreto.
A continuación se exponen algunos de los identificadores más utilizados en la programación C/C++ para Windows, junto con una breve descripción de sus características.
WINAPI | En realidad no se refiere a un tipo de dato, sino a una convención de llamada a función ( 4.4.6a). En las primitivas versiones de Windows, este identificador se refería a la convención _pascal. En las versiones de 32 bits se corresponde con la convención estándar de llamada. En particular, la función WinMain, que en estas aplicaciones sustituye a la función main del C/C++ estándar, utiliza esta convención. |
CALLBACK | Es otra convención de llamada. En particular para aquellas fuciones de
retrollamada ("call-back") de la aplicación, que deben ser
invocadas por el Sistema Operativo. Es el caso de los denominados
"window procedures" y "dialog procedures".
Inicialmente se referían a la convención FAR PASCAL, pero actualmente
son llamadas estándar (_stdcall). En concreto, el "window
procedure" responde al siguiente prototipo:
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); |
LPSTR | Punteros a matrices de caracteres. Generalmente cadenas alfanuméricas al estilo C clásico, terminadas en el carácter nulo (NTBSs 3.2.3f). Definidas como char FAR* [3] |
LPCSTR | Análogos a los anteriores pero referidos a matrices de caracteres constantes (de solo lectura). Definido como const char FAR* |
UINT | Un tipo de entero sin signo cuyo tamaño depende del entorno (Windows 16, 32 o 64 bits). Es sinónimo de unsigned int, y generalmente es utilizado en sustitución del tipo WORD, excepto en las contadas ocasiones en que se desea un valor sin signo de 16 bits aunque se trate de plataformas de 32 o 64 bits. |
LRESULT | Este es el tipo devuelto por las funciones "call-back" (window procedure y dialog procedure). |
WPARAM | Las funciones call-back aceptan cuatro parámetros, dos de los cuales son de propósito general. Este tipo corresponde a uno de ellos . |
LPARAM | Tipo del segundo parámetro de uso general de las funciones "call-back". |
LPVOID | Puntero genérico, equivalente a void*. Suele utilizarse con preferencia a LPSTR. |
En la mayoría de los casos, el intercambio de datos entre las aplicaciones Window y la API Sistema, se concreta en estructuras (en el sentido C del término) que se definen mediante los oportunos "defines" y que se manejan a través de punteros, que aquí son conocidos como manejadores ("hanles"). Muchas funciones de la API, tanto de servicios generales como de servicios gráficos (GDI), reciben y devuelven estos "handles". Que a su vez se presentan mediante distintos identificadores que finalmente son traducidos en la fase de preproceso a punteros-a-estructuras de distinto tipo. A continuación se relacionan algunos de los más frecuentes. |
|
HANDLE | manejador genérico. Debe ser sustituido por uno más específico siempre que sea posible. |
HINSTANCE | handle a instancia de una aplicación (por ejemplo, el programa en ejecución). |
HDC | handle a contexto gráfico DC ("device context"). Un DC se materializa en una estructura que define un conjunto de objetos relacionados con la GDI de Windows (objetos gráficos); sus atributos y modos que afectan a sus salidas. Entre estos objetos están una pluma "pen" para trazado de líneas; un pincel "brush", para relleno de áreas; un mapa de bits "bitmap"; una paleta de colores; una referencia al área "canvas" en la que se realizarán las operaciones de dibujo, y una región dentro de ella. |
HMODULE | handle a módulo. |
HBITMAP | handle a bitmap. |
HLOCAL | handle a local. |
HGLOBAL | handle a global. |
HTASK | handle a tarea (proceso). |
HFILE | handle a fichero. |
HRSRC | handle a recurso. |
HGDIOBJ | handle a objeto de la interfaz de diseño gráfico GDI ("Graphic Design Interface"). Excepto metaficheros |
HMETAFILE | handle a metafichero.
Nota: las aplicaciones para el SO Windows utilizan dos herramientas para almacenar imágenes: los metaficheros ("metafiles") y los mapas de bits ("bitmaps"). Los metaficheros son matrices de estructuras de longitud variable que, al contrario que los mapas de bits, almacenan la información gráfica en un formato independiente de cualquier dispositivo concreto (device-independent format). |
HDWP | handle a una estructura DeferWindowPos(). Esta función cambia la estructura que define la posición y tamaño de una ventana. |
HACCEL |
handle a tabla de aceleradores. Estas son matrices de estructuras ACCEL que definen combinaciones de teclas aceleradoras ("accelerator's keystrokes") de un hilo de ejecución ("thread"). Responden a la siguiente definición:
typedef struct tagACCEL { |
HDRVR | handle a controlador de dispositivo ("driver"). |
HWND | handle a caja una ventana. Por ejemplo una caja de diálogo ("dialog box"); un botón; etc. |
A continuación se muestran algunos de estos typedef tomados de los
ficheros de cabecera correspondientes [1]. Como puede
comprobar, algunos están definidos en función de otros en un
proceso recursivo, aunque el preprocesador las traslada finalmente a su
definición definitiva. Por ejemplo, WPARAM es UINT que finalmente es
considerado por el compilador equivalente unsigned int [2].
typedef char CHAR, CCHAR, *PCCHAR;;
typedef unsigned char BYTE, UCHAR, *PUCHAR;
typedef unsigned short WORD, USHORT, ATOM, *PUSHORT;
typedef short SHORT, *PSHORT;
typedef unsigned int UINT, WPARAM;
typedef int INT, HFILE;
typedef HICON HCURSOR;
typedef double DOUBLE;
typedef unsigned long DWORD, ULONG, *PULONG;
typedef long BOOL, LONG, LPARAM, LRESULT, *PLONG;
typedef float FLOAT, *PFLOAT;
typedef unsigned char UCHAR,*PUCHAR;typedef wchar_t WCHAR, TCHAR, OLECHAR;
typedef char *PSZ;
typedef unsigned int * PUINT;
typedef TCHAR TBYTE,*PTCH,*PTBYTE;
typedef TCHAR *LPTCH,*PTSTR,*LPTSTR,*LP,*PTCHAR;
typedef const TCHAR *LPCTSTR;
typedef void *HANDLE;
typedef PVOID HANDLE;
typedef HANDLE HDWP, *PHANDLE,*LPHANDLE;typedef DWORD COLORREF; // Valores de color RGB Windows
typedef hyper LONGLONG;
typedef DWORD * LPCOLORREF;
typedef CHAR *PCHAR, *LPCH, *PCH, *NPSTR, *LPSTR, *PSTR;
typedef const CHAR *LPCCH, *PCCH, *LPCSTR, *PCSTR ;
typedef WCHAR *PWCHAR, *LPWCH, *PWCH, *NWPSTR, *LPWSTR, *PWSTR;
typedef const WCHAR *LPCWCH, *PCWCH, *LPCWSTR, *PCWSTR, *LPCCH, *PCCH;
typedef VOID void
typedef void *PVOID,*LPVOID;
[1] La mayoría en los ficheros de cabecera windef.h y winnt.h. Consulte el directorio include de su compilador. También puede consultar las páginas de Microsoft donde se dan las definiciones "oficiales" de los distintos tipos usados por la API de Windows: MSDN
[2] Recuerde que estas definiciones son dependientes del entorno de ejecución, por lo que deben tomarse con ciertas precauciones.
[3] Las versiones de Windows de 32 bits, no utilizan los conceptos cercano/lejano para los punteros (NEAR poiner / LONG pointer), que son reminiscencias de las versiones 16 bits. En consecuencia, aunque los prefijos LP (Long pointer) y P (near pointer) se siguen utilizando, son equivalentes. Por ejemplo, char FAR* es equivalente a char*, y en consecuencia, LPSTR y PSTR son equivalentes; también LPCSTR y CSTR; etc.