[ 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