Ver Mensaje Individual
  #6  
Antiguo 22-12-2008
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.210
Reputación: 22
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Dado el interés que se mostró por este tema y que he ido publicando de forma desordenada código para el manejo de iconos en la sección de recursos de un ejecutable o dll, voy a tratar de ordenar ese código siguiendo este hilo. Como esto será un poco largo, lo voy a dividir en varios post.

En primer lugar, he de aclarar que los Iconos de le sección de recursos están agrupados en grupos con una cabecera de tipo GRPICONDIR. En esa cabecera tenemos, entre otras cosas, el número de imágenes que contiene y un array de entradas a cada imagen cada entrada es del tipo MEMICONDIRENTRY o GRPICONDIRENTRY (son lo mismo).

Los archivos de iconos se comportan igual pero únicamente contienen un sólo Grupo con una o varias imágenes. Su cabecera es del tipo ICONDIR y este contiene, entre otras cosas, el número de iconos y las entradas correspondientes a cada uno del tipo ICONDIRENTRY.

Las definiciones están publicadas aquí y su fuente está aquí.

Dicho esto, lo primero que tenemos que conseguir es enumerar los recursos por su tipo, lo que nos interesa es el tipo RT_GROUP_ICON que son los grupos de iconos, es decir enumeraremos esos grupos sabiendo que cada uno puede tener varias imágenes de iconos de distinto tamaño, resolución y número de colores.

Código:
//------------------------------------------------------------------------------
// Funciones de enumeración de resources
//------------------------------------------------------------------------------
// Declaraciones previas

// Definición del tipo de función que acepta EnumResourceNames
typedef BOOL (__stdcall *TP)();

// Estructura para comunicar EnumResourceNames con la función de enumeración
struct TResInGr{
   int Count;
   int Id;
   char* ResName;
   HRSRC hRes;
};

// Función de enumeración para la cuenta de elementos y encontrar un Resource
BOOL CALLBACK
EnumResGrProc(HANDLE hModule, LPCTSTR lpszType, LPTSTR lpszName, LONG lParam)
{
   TResInGr *Res =  (TResInGr*)lParam;
   if(Res->Count == Res->Id){
     Res->ResName = lpszName;
     Res->hRes = ::FindResource(hModule, lpszName, lpszType);
   }
   Res->Count++;
   return true;
}

// Devuelve el Nº de Elementos de lpszType
int GetCountRes(HANDLE hModule, LPCTSTR lpszType)
{
   TResInGr Res = {0};
   Res.Id = -1;
   EnumResourceNames(hModule, lpszType, (TP)EnumResGrProc, LPARAM(&Res));
   return Res.Count;
}

// Devuelve el Nº de Elementos de lpszType
int GetCountRes(char *FuenteExe, LPCTSTR lpszType)
{
   HANDLE hModule = LoadLibrary(FuenteExe);
   int Count = GetCountRes(hModule, lpszType);
   FreeLibrary(hModule);
   return Count;
}

// Devuelve un HRSRC con Indice Id del array de resources lpszType
// Id: Indice del Grupo de iconos como si fuese una array comenzando por 0
HRSRC FindResource(HMODULE hModule, int Id, LPCTSTR lpszType)
{
   TResInGr Res = {0};
   Res.Id = Id;
   EnumResourceNames(hModule, lpszType, (TP)EnumResGrProc, LPARAM(&Res));
   return Res.hRes;
}
Estas funciones enumeran la sección de recursos con el propósito de contarlos con GetCountRes y encontrar un recurso determinado por su íncice, comenzando desde 0, con FindResource. Esta última función, a diferencia de la API FindResource, toma los índices como un int. La API FindResource toma los índices como una cadena formada por el carácter # seguida de un número que comienza por el 1. El primer recurso es el “#1”.

Por el momento doy por terminada esta primera parte.

Saludos.

Última edición por escafandra fecha: 23-12-2008 a las 01:24:12.
Responder Con Cita