Club Delphi  
    Paypal   FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros entornos y lenguajes > C++ Builder
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

 
 
Herramientas Buscar en Tema Desplegado
  #8  
Antiguo 23-12-2008
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.210
Poder: 22
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Continúo con la extracción de iconos de la sección de recursos de un ejecutable.

GetFileMemIconFromModule está diseñada para extraer un grupo de imágenes del recurso en un buffer que pueda ser escrito directamente a un archivo.ico. El formato es un buffer con una cabecera ICONDIR, sus entradas a las imágenes y éstas mismas. Un archivo de este tipo, a diferencia con la sección de recursos de un ejecutable, sólo tiene un grupo de iconos definido en su cabecera, aunque lo habitual es que, ese grupo sólo tenga una imagen, nada impide que tenga muchas más de diferente resolución y número de colores.

Código:
//------------------------------------------------------------------------------
// Devuelve en Buffer Una imagen de archivo.ico para poder guardar en disco.
// Devuelve el tamaño de la memoria de archivo de un Icono de un hModule
// Retorna 0 si falla, 1 si Buffer==0 y AllSize si devuelve el valor en Buffer.
// Si Buffer = NULL, devuelve en Size el tamaño necesario para el buffer
// Id: Indice del Grupo de iconos como si fuese una array comenzando por 0
int GetFileMemIconFromModule(HMODULE hModule, int Id, void* Buffer, int *Size)
{
    LPICONDIR IconDir;
    LPICONDIRENTRY IconEntry;
    LPICONIMAGE  resIconImage;
    LPGRPICONDIR grpIconDir;
    HRSRC hRes;        // handle para res. info. del ejecutable
    int IconsCount = 0;
    int AllSize = sizeof(ICONDIR)-sizeof(ICONDIRENTRY);
    DWORD ImageOffset;

    // Cuento cuantos iconos tiene el recurso y la memoria necesaria
    hRes = FindResource(hModule, Id, RT_GROUP_ICON);
    if(hRes){
       grpIconDir = (LPGRPICONDIR)LoadResource(hModule, hRes);
       IconsCount = grpIconDir->idCount;
       for(int n=0; n<IconsCount; n++)
         AllSize += sizeof(ICONDIRENTRY) + grpIconDir->idEntries[n].dwBytesInRes;
    }

    if(IconsCount==0){
      *Size = 0;
      return 0;
    }
    if(Buffer == 0 ){
      *Size = AllSize;
      return 1;
    }
    if(*Size < AllSize) return 0;

    // Preparo la Cabecera General grpIconDir
    setmem(Buffer, 0, AllSize);
    IconDir  = (LPICONDIR)Buffer;
    IconDir->idReserved = 0;
    IconDir->idType = 1;
    IconDir->idCount = IconsCount;
    // IconEntry apunta a la entrada del primer icono IconDir->idEntries[0]
//    IconEntry = LPICONDIRENTRY(Buffer + sizeof(ICONDIR) - sizeof(ICONDIRENTRY));
    IconEntry = &IconDir->idEntries[0];

    // Localizar el ICON resource en el ejecutable y sus Imagenes.
    hRes = NULL;
    ImageOffset = sizeof(ICONDIR) + (sizeof(ICONDIRENTRY)*(IconDir->idCount-1));
    // Recorro las imágenes del recurso y preparo las entradas y las imágenes en el Buffer
    for(int n=0; n<IconsCount; n++){
      int nID = grpIconDir->idEntries[n].nID;
      hRes = ::FindResource(hModule, MAKEINTRESOURCE(nID), RT_ICON);
      resIconImage = (ICONIMAGE*)LoadResource(hModule, hRes);
      IconEntry[n].bWidth = resIconImage->icHeader.biWidth;
      IconEntry[n].bHeight = resIconImage->icHeader.biHeight/2;
      IconEntry[n].bColorCount =  NColors(resIconImage->icHeader.biBitCount);
      IconEntry[n].bReserved = 0;
      IconEntry[n].wPlanes = 1;
      IconEntry[n].wBitCount = resIconImage->icHeader.biBitCount;
      IconEntry[n].dwBytesInRes = SizeofResource(hModule, hRes);
      IconEntry[n].dwImageOffset = ImageOffset;
      // Copio la imagen
      memcpy((BYTE*)Buffer+ImageOffset, resIconImage, IconEntry[n].dwBytesInRes);
      ImageOffset += IconEntry[n].dwBytesInRes;
    }

    return AllSize;
}
Como puede observarse, al igual que la función ExtractResIconFromModule, se recorren todas las imágenes del grupo. El código puede ser base para otro que obtenga uno o varios iconos en particular, según determinado criterio, y proporcionar un buffer sólo con esas imágenes. Para eso será necesario calcular previamente el tamaño del buffer y luego rellenarlo cuidadosamente.

Para ilustrar el uso de esta función propongo un código que guarda el grupo de iconos en un archivo de iconos.ico, SaveResIconToFile:
Código:
//------------------------------------------------------------------------------
// Guarda en disco File.ico el grupo de Icono de un exe o dll
// Id: Indice del Grupo de iconos como si fuese una array comenzando por 0
bool SaveResIconToFile(char *FuenteExe, char* DestFileName, int Id)
{
   BYTE* Buffer;
   int Size;
   HMODULE hModule;
   hModule = LoadLibrary(FuenteExe);

   // Calculo el tamaño necesario para el Buffer
   GetFileMemIconFromModule(hModule, Id, 0, &Size);
   Buffer = new BYTE[Size];
   
   // Extraigo del ejecutable (hModule) el grupo de iconos que obtengo en el Buffer
   // Este Buffer es una imagen en memoria de un archivo.ico que se puede guardar directamente.
   int S = GetFileMemIconFromModule(hModule, Id, Buffer, &Size);
   if(S==0) return false;

   // Creo y guardo el archivo de iconos
   HANDLE hFile = CreateFile(DestFileName, GENERIC_WRITE, 0, NULL,
                   CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

   unsigned long dwBytesWritten;

   if (INVALID_HANDLE_VALUE != hFile){
       WriteFile(hFile, Buffer, Size, &dwBytesWritten, NULL);
       CloseHandle(hFile);
   }

   FreeLibrary(hModule);
   delete [] Buffer;
   return (dwBytesWritten == Size);
}
Como comentaba mas arriba, pueden crearse mas funciones para escojer iconos concretos y to todo el grupo, las bases están puestas en esta serie de post.

Saludos.
Responder Con Cita
 



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Border Icon pmcastilla Varios 2 10-09-2007 16:49:29
Componente Tray Icon marceloalegre Varios 1 06-06-2005 13:51:21
Try Icon narvaez.om Varios 1 03-05-2005 22:13:06
Tray Icon con abcTrayIcon Alexander Varios 0 29-09-2004 21:22:28
mouse Icon en un TQuery jymy788 Varios 4 17-09-2004 13:31:16


La franja horaria es GMT +2. Ahora son las 11:06:00.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi