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
  #7  
Antiguo 22-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
Aprovecho un ratito para publicar otra parte:

Explicado los conceptos preliminares y la enumeración de recursos, pasamos a la extracción se los recursos. He escrito dos funciones bastante similares.

La primera, ExtractResIconFromModule, extrae un grupo de imágenes de la sección de recursos de un ejecutable o dll. La extracción es un buffer que contiene el binario del resource. La segunda, GetFileMemIconFromModule, hace lo propio pero en un buffer imagen de un archivo.ico. De cada uno se estos buffer se podrá extraer, entonces, una imagen de un icono individual, pero esto lo realizarán otras funciones.

ExtractResIconFromModule, extrae un grupo de imágenes en un buffer de memoria con cabecera GRPICONDIR (o MEMICONDIR) con las entradas a cada imagen y estas. Este buffer puede usarse para pasar el recurso entero tipo RT_GROUP_ICON a una dll o ejecutable. Esto lo realizará otra función, AddIconToExe.
Código:
//---------------------------------------------------------------------------
// Devuelve un ResMem Icon de un hModule
// 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.
// Precisa de un Buffer previo de tamaño Size
// 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 ExtractResIconFromModule(HMODULE hModule, int Id, void* Buffer, int* Size)
{
    LPGRPICONDIR grpIconDir;
    LPGRPICONDIR grpSrcIconDir;
    LPGRPICONDIRENTRY grpIconEntry;
    LPICONIMAGE  grpIconImage;
    LPICONIMAGE  resIconImage;
    BYTE* IconMem = (BYTE*)Buffer;
    HRSRC hRes;        // handle para res. info. del ejecutable
    int IconsCount = 0;
    int AllSize = sizeof(GRPICONDIR);

    // Cuento cuantos iconos tiene el recurso y la memoria necesaria
    hRes = FindResource(hModule, Id, RT_GROUP_ICON);
    if(hRes){
       grpSrcIconDir = (LPGRPICONDIR)LoadResource(hModule, hRes);
       IconsCount = grpSrcIconDir->idCount;
       for(int n=0; n<IconsCount; n++)
         AllSize += sizeof(ICONDIRENTRY) + grpSrcIconDir->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
    grpIconDir  = (LPGRPICONDIR)IconMem;
    grpIconDir->idReserved = 0;
    grpIconDir->idType = 1;
    grpIconDir->idCount = IconsCount;
    grpIconEntry = LPMEMICONDIRENTRY(IconMem + sizeof(GRPICONDIR) - sizeof(GRPICONDIRENTRY));

    // Localizar el ICON resource en el ejecutable y sus Imagenes.
    hRes = NULL;
    grpIconImage = (LPICONIMAGE)((BYTE*)grpIconDir + sizeof(GRPICONDIR) + (sizeof(GRPICONDIRENTRY)*(grpIconDir->idCount-1)));
    for(int n=0; n<IconsCount; n++){
      int nID = grpSrcIconDir->idEntries[n].nID;
      hRes = ::FindResource(hModule, MAKEINTRESOURCE(nID), RT_ICON);
      // Preparo las cabeceras Entrada de cada Imagen
      resIconImage = (ICONIMAGE*)LoadResource(hModule, hRes);
      grpIconEntry[n].bWidth = resIconImage->icHeader.biWidth;
      grpIconEntry[n].bHeight = resIconImage->icHeader.biHeight/2;
      grpIconEntry[n].bColorCount =  NColors(resIconImage->icHeader.biBitCount);
      grpIconEntry[n].bReserved = 0;
      grpIconEntry[n].wPlanes = 1;
      grpIconEntry[n].wBitCount = resIconImage->icHeader.biBitCount;
      grpIconEntry[n].dwBytesInRes = SizeofResource(hModule, hRes);
      grpIconEntry[n].nID = n;
      // Copio la imagen
      memcpy(grpIconImage, resIconImage, grpIconEntry[n].dwBytesInRes);
//      grpIconImage = (LPICONIMAGE)((BYTE*)grpIconImage + grpIconDir->idEntries[n-1].dwBytesInRes);
      grpIconImage = (LPICONIMAGE)((BYTE*)grpIconImage + grpIconEntry[n].dwBytesInRes);
    }

    return AllSize;
}
Y para ilustrar el uso de esta función voy a colocar el código de AddIconToExe, que añade el recurso extraído con ExtractResIconFromModule, en un ejecutable o una dll:

Código:
//---------------------------------------------------------------------------
// grpIconDir : Buffer con el recurso del tipo RT_GROUP_ICON extraido con  ExtractResIconFromModule
// DestinoExe: Nombre de un ejecutable o dll
// ResName: Nombre que se le dará al recurso añadico al ejecutable o dll
// BorraIconResPrevio: Si es trae se borraran los recursos previos RT_GROUP_ICON del ejecutable o dll
bool  AddIconToExe(LPGRPICONDIR grpIconDir, char *DestinoExe, char* ResName, bool BorraIconResPrevio)
{
   LPGRPICONDIRENTRY IconEntry;
   LPICONIMAGE  IconImage;
   LPBYTE lpResLock;
   bool Result = true;

   if(!grpIconDir) return false;
   if(!DestinoExe || !*DestinoExe) return false;
   if(!ResName || !*ResName) return false;

   // Crea espacio para las cabeceras del icono recurso
   int HeaderSize = sizeof(GRPICONDIR)+(sizeof(GRPICONDIRENTRY)*(grpIconDir->idCount-1));

   HANDLE hUpdateRes = BeginUpdateResource(DestinoExe, BorraIconResPrevio);
   // Localizo la primera imagen del icono a pasar al .exe
   IconImage = (LPICONIMAGE)((BYTE*)grpIconDir + sizeof(GRPICONDIR) + (sizeof(GRPICONDIRENTRY)*(grpIconDir->idCount-1)));
   for(int n=0; n<grpIconDir->idCount; n++){
     lpResLock = (BYTE*)LockResource(IconImage);
     // Abrir el fichero donde añadir el icono.
     if (hUpdateRes != NULL){
       // Actualizar el resource destino
       Result &= UpdateResource(hUpdateRes,
         RT_ICON,
         MAKEINTRESOURCE(grpIconDir->idEntries[n].nID),
         MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
         lpResLock,
         grpIconDir->idEntries[n].dwBytesInRes);
     }
     // Localizo la siguiente Imagen
     IconImage = (LPICONIMAGE)((BYTE*)IconImage + grpIconDir->idEntries[n].dwBytesInRes);
   }

   // Y la grabamos como "indice" o cabecera de grupo de iconos
   Result &= UpdateResource(hUpdateRes, RT_GROUP_ICON,
        ResName,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
        grpIconDir, HeaderSize);

   // Escribir los cambios y cerrar.
   Result &= EndUpdateResource(hUpdateRes, FALSE);

   return Result;
}
Y para terminar de ilustrar estas funciones, propongo esta otra que hace uso de las dos:
Código:
//------------------------------------------------------------------------------
// Pasa todas las imágenes del primer Grupo Icono (principal por defecto del ejecutable)
// de un exe (o dll) a otro
bool AddIconToExe(char *FuenteExe, char *DestinoExe, char* ResName, bool BorraIconResPrevio)
{
    bool Result;
    BYTE* Buffer;
    int Size;    
    LPGRPICONDIR grpIconDir;
    HMODULE hModule;
    hModule = LoadLibrary(FuenteExe);

    // Calculo el tamaño necesario para el Buffer
    ExtractResIconFromModule (hModule, 0, 0, &Size);
    Buffer = new BYTE[Size];

    // Extraigo del ejecutable (hModule) el primer grupo de iconos que obtengo en el Buffer
    ExtractResIconFromModule(hModule, 0, Buffer, &Size);
    grpIconDir  = (LPGRPICONDIR)Buffer;
    
    FreeLibrary(hModule);
    if(grpIconDir)  // Si el Buffer es válido
       Result = AddIconToExe(grpIconDir, DestinoExe, ResName, BorraIconResPrevio);
    else   // Si el buffer no es válido
       Result = false;

    // Libero la memoria del Grupo de iconos antes de retornar.
    delete [] Buffer;
   
    return Result;
}
En el siguiente post publicaré el modo de guardar en un archivo, un Grupo de Iconos con las funciones GetFileMemIconFromModule y SaveResIconToFile.

Saludos.

PD: Edito para añadir otro ejemplo: AddIconToExe

Última edición por escafandra fecha: 23-12-2008 a las 01:47:11.
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 10:45:51.


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