[ contenidos | #winprog ]

Uso de Recursos

Puedes mirar los ap�ndices al final del tutorial para mas informaci�n sobre el uso de recursos con VC++ y BC++.

Antes de ver el tema en profundidad voy a cubrir el tema de recursos as� no tendr� que reescribir el mismo en cada secci�n. Por ahora no necesitas compilar el codigo, solo es un ejemplo.

Los recursos son porciones pre-definidas de datos que se almacenan en formato binario dentro de los archivos ejecutables y se organizan dentro de un archivo con extensi�n ".rc" (resource script). Los compiladores comerciales cuentan con un editor visual de recursos que permite crear recursos sin editar manualmente este archivo. A veces la �nica manera de poder crear un recurso es editar este archivo manualmente sobre todo si tu compilador no tiene un editor visual o no soporta la caracter�sitica exacta que necesitas.

Desafortunadamente, no todos los compiladores manejan los recursos de la misma manera. Har� lo mejor que pueda para explicar las caracter�sticas mas comunes que son necesarias para trabajar con recursos en forma general.

El editor de recursos inclu�do con MSVC++ hace muy dif�cil la tarea de editar los recursos manualmente, debido a que fuerza un formato propio en ellos y si intentas guardar uno que has creado manualmente estropea completamente el archivo. En general no deber�as preocuparte por crear archivos de recursos desde cero, pero conocer como modificarlos manualmente puede ser muy �til. Otra incomodidad es que MSVC++ nombrar� el archivo de recuros por default con el nombre "resource.h" a�n si deseas llamarlo con otro nombre. Utilizaremos este con el prop�sito de simplicidad para este documento, pero te mostrar� como cambiarlo en el ap�ndice sobre compiladores.

Primero miremos un archivo de recursos bastante simple, con solo un �cono:

#include "resource.h"

IDI_MYICON ICON "my_icon.ico"

Este es todo el archivo. IDI_MYICON es el identificador del recurso, ICON es el tipo de recurso y "my_icon.ico" es el nombre del archivo externo que contiene al �cono. Esto deber�a funcionar en cualquier compilador.

�Que hay acerca de #include "resource .h"?. Bien tu programa necesita una forma de indentificar el �cono y la mejor forma de hacerlo es asign�ndole a este un �nico ID (IDI_MYICON). Podemos hacer esto creando el archivo de cabecera "resource.h" e incluir �ste tanto en el archivo de recursos (.rc) como en el programa (.c)

#define IDI_MYICON  101

Como puedes ver, hemos asignado a IDI_MYICON el valor 101. De ahora en mas podr�amos olvidarnos del identificador y simplemente usar 101 cada vez que necesitamos referenciar el �cono. Pero IDI_MYICON es un poco mas claro, mas representativo y mas facil de recordar, sobre todo si estamos trabajando con una gran cantidad de recursos.

Ahora supongamos que agregamos un recurso MENU:

#include "resource.h"

IDI_MYICON ICON "my_icon.ico"

IDR_MYMENU MENU
BEGIN
    POPUP "&File"
    BEGIN
        MENUITEM "E&xit", ID_FILE_EXIT
    END
END

Nuevamente IDR_MYMENU es el nombre del recurso y men� es el tipo. Ahora observa el BEGIN y el END. Algunos editores o compiladores utilizan la llave que abre { en lugar de BEGIN y la llave que cierra } en lugar de END. Si tu compilador soporta ambos, puedes elejir el que mas te guste si solo soporta uno u otro debrer�s hacer los reemplazos necesarios en el codigo fuente para que esto funcione.

Tambi�n he agregado un nuevo identificador, ID_FILE_EXIT, por lo tanto necesitamos agregarlo al archivo de cabecera de los recursos (resource.h) para poder usarlo dentro de nuestro porgrama.

#define IDI_MYICON  101

#define ID_FILE_EXIT	4001

Generar y mantener un registro de todos los identificadores de recursos puede ser una tarea costosa cuando trabajamos con grandes proyectos, esta es la raz�n por la que muchas personas utilizan un editor visual de recursos, el cual se encarga de hacer todo este trabajo por nosotros. Aunque pueden generar problemas de vez en cuando y podr�as finalizar con multiples recursos con el mismo ID o problemas similares, es bueno ser capaz de ir y poder corregir esos errores uno mismo.

Ahora veamos un ejemplo de como usar un recurso dentro de un programa.

    HICON hMyIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MYICON));

El primer par�metro de LoadIcon( ) y muchos otros recursos que utilizan funciones es el handle a la instancia actual (la que obtenemos en WinMain( ) y que tambi�n puede ser recuperada utilizando la funci�n GetModuleHandle( ), como lo demostramos en secciones anteriores). El segundo es el identificador del recurso.

Probablemente te est�s preguntando que es MAKEINTRESOURCE( ) y posiblemente por qu� LoadIcon() toma un par�metro de tipo LPCTSTR en vez de, por ejemplo UINT, cuando le estamos pasando un ID. Todo lo que MAKEINTRESOURCE hace es convertir un entero (el tipo de nuestro ID) a un LPCTSTR que es lo que LoadIcon( ) espera. Esto nos da una segunda forma de identificar recursos: utilizando strings. Hoy en dia casi nadie hace esto, por lo tanto no voy a entrar mucho en detalle. B�sicamente si no utilizas #define para asignar un valor entero a tus recursos, entonces el nombre es interpretado como un string y podemos referenciar los recursos dentro de nuestro programa de la siguiente manera:

    HICON hMyIcon = LoadIcon(hInstance, "MYICON");

Cuando se les pasa un valor entero LoadIcon( ) y otras APIs que cargan recursos pueden identificar la diferencia entre un entero y un puntero a un entero chequeando la palabra superior de dicho valor. Si es cero (como podr�a ser el caso de un entero con un valor menor a 65535) entonces asume que se trata del ID de un recurso. Esto efectivamente nos limita a usar IDs inferiores a 65535, que a menos que tengas una gran cantidad de recursos, no deberi� ser un problema. Si es distinto de cero, entonces asume que el valor es un puntero y busca el recurso por el nombre. Nunca le conf�es este trabajo a la API a menos que est� explicitamente establecido en la documentaci�n. Por ejemplo, esto no funciona para comandos del men� como ID_FILE_EXIT debido a que solo pueden ser enteros.


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

Versi�n en Espa�ol: Federico Pizarro - 2003