Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Gráficos
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #21  
Antiguo 18-12-2008
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Lightbulb

Cita:
Empezado por _cero_ Ver Mensaje
Pues no quería contestar hasta que tuviera una función concreta, pero me he atorado en la extracción del icono de los recursos a un archivo .ico, ya intente la función que dejo escafandra, pero no le entiendo mucho asi que por favor, me podrían ayudar con la extracción de un icono (ahora si proveniente de un exe o dll), a un directorio digamos "C:\".
Bueno, no se donde te has "atorado" pero quizás es porque ExtractResIconFromModule está pensada para mapear un resource en memoria no para salvar archivos. Esto te viene bien para extraer un icono que quieras incluir en un ejecutable pero no para salvar un archivo.ico. No es lo mismo la forma de tratar un resource en memoria que un archivo.ico. Aquí podrás estudiarlo.


Te dejo mas código que te sirve para lo que pretendes (vas a terminar con mi arsenal):

Para extraer un mapa de memoria del icono en formato archivo.ico
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));
    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;
}
Para extraer y salvar un icono procedente de un exe o dll:
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);

   GetFileMemIconFromModule(hModule, Id, 0, &Size);
   Buffer = new BYTE[Size];
   int S = GetFileMemIconFromModule(hModule, Id, Buffer, &Size);
   if(S==0) return false;

   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);
}
Saludos.

Última edición por escafandra fecha: 18-12-2008 a las 23:33:35.
Responder Con Cita
  #22  
Antiguo 18-12-2008
_cero_ _cero_ is offline
Miembro
 
Registrado: abr 2007
Posts: 147
Poder: 18
_cero_ Va por buen camino
Unhappy

Lo que pasa es que cuando yo trabajaba con los recursos de mi aplicación usaba “TResourceStream” y “TFileStream” para extraer algo de los recursos a un archivo x, pero creo que esto no se puede usar con recursos ajenos, entonces intento usar “FindResource” y “LoadResource” para cargar los recursos ajenos, y aquí es donde me atoro porque sé que “LoadResource” regresa la dirección de estos recursos, pero como puedo trabajar con este resultado?, lo puedo asignar a un Ticon o algo parecido?.

pd. Gracias por el código escafandra, ya lo estoy estudiando.
Responder Con Cita
  #23  
Antiguo 18-12-2008
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Bueno LoadResource te devuelve un HGLOBAL. No lo he probado, pero seguro que ese puntero es un LPGRPICONDIR. De las funciones que te he dejado, ExtractResIconFromModule te devuelve un puntero tipo LPGRPICONDIR.

No termino de entender lo que quieres hacer , pesé que querías guardar en un archivo.ico una imagen de un icono extraído de un resource de dll o exe. Si es así la respuesta esta aquí.

Saludos.
Responder Con Cita
  #24  
Antiguo 19-12-2008
_cero_ _cero_ is offline
Miembro
 
Registrado: abr 2007
Posts: 147
Poder: 18
_cero_ Va por buen camino
Smile

Pues gracias por todo escafandra, ya implemente las funciones que dejaste y tuve que declarar algunas estructuras (y no sé si lo hice correctamente, pero no me funciono hasta que lo hice), no sé si es por esto que “SaveResIconToFile” me devuelve false y no me crea el icono, pero al menos ya tengo con que orientarme y seguirle intentando para extraer los iconos gracias.
Aquí los tipos que declare:
Código:
typedef struct
{
BYTE bWidth;
BYTE bHeight;
BYTE bColorCount;
BYTE bReserved;
WORD wPlanes;
WORD wBitCount;
DWORD dwBytesInRes;
DWORD dwImageOffset;
}ICONDIRENTRY, *LPICONDIRENTRY;

typedef struct
{
  BYTE bWidth;
  BYTE       bHeight;
  BYTE       bColorCount;
  BYTE       bReserved;
  WORD       wPlanes;
  WORD       wBitCount;
  DWORD       dwBytesInRes;
  WORD       nID;
} GRPICONDIRENTRY, *LPGRPICONDIRENTRY;

typedef struct
{
  WORD idReserved;
  WORD idType;
  WORD idCount;
  GRPICONDIRENTRY idEntries[1];
} GRPICONDIR, *LPGRPICONDIR;

typedef struct
{
  BITMAPINFOHEADER icHeader;
  RGBQUAD icColors[1];
  BYTE icXOR[1];
  BYTE icAND[1];
} ICONIMAGE, *LPICONIMAGE;

typedef struct
{
  WORD idReserved;
  WORD idType;
  WORD idCount;
  ICONDIRENTRY idEntries[1];
}ICONDIR, *LPICONDIR;
Responder Con Cita
  #25  
Antiguo 19-12-2008
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Si creí que tenias claro de donde salían las definiciones de las estructuras usadas. Yo tengo esto en un archivo que denomino iconos.h:
Código:
#ifndef iconosH
#define iconosH
//---------------------------------------------------------------------------
// Tomado de http://msdn.microsoft.com/en-us/library/ms997538.aspx 
// Modificado del original. 

// Necesario para alinear a Word el compilador
#pragma pack( push )
#pragma pack( 2 )

// These first two structs represent how the icon information is stored
// when it is bound into a EXE or DLL file. Structure members are WORD
// aligned and the last member of the structure is the ID instead of
// the imageoffset.

typedef struct
{
    BYTE    bWidth;               // Width of the image
    BYTE    bHeight;              // Height of the image (times 2)
    BYTE    bColorCount;          // Number of colors in image (0 if >=8bpp)
    BYTE    bReserved;            // Reserved
    WORD    wPlanes;              // Color Planes
    WORD    wBitCount;            // Bits per pixel
    DWORD    dwBytesInRes;         // how many bytes in this resource?
    WORD    nID;                  // the ID
} MEMICONDIRENTRY, *LPMEMICONDIRENTRY, GRPICONDIRENTRY, *LPGRPICONDIRENTRY;

typedef struct
{
    WORD            idReserved;   // Reserved
    WORD            idType;       // resource type (1 for icons)
    WORD            idCount;      // how many images?
    MEMICONDIRENTRY    idEntries[1]; // the entries for each image
} MEMICONDIR, *LPMEMICONDIR, GRPICONDIR, *LPGRPICONDIR;


// These next two structs represent how the icon information is stored
// in an ICO file.
typedef struct
{
    BYTE    bWidth;               // Width of the image
    BYTE    bHeight;              // Height of the image (times 2)
    BYTE    bColorCount;          // Number of colors in image (0 if >=8bpp)
    BYTE    bReserved;            // Reserved
    WORD    wPlanes;              // Color Planes
    WORD    wBitCount;            // Bits per pixel
    DWORD    dwBytesInRes;         // how many bytes in this resource?
    DWORD    dwImageOffset;        // where in the file is this image
} ICONDIRENTRY, *LPICONDIRENTRY;

typedef struct
{
    WORD             idReserved;   // Reserved
    WORD             idType;       // resource type (1 for icons)
    WORD             idCount;      // how many images?
    ICONDIRENTRY idEntries[1]; // the entries for each image
} ICONDIR, *LPICONDIR;

#pragma pack( pop )

//---------------------------------------------------------------------------
#endif
Es necesario que lo coloques como te lo pongo pues algunas estructuras necesitan compliarse con una alineación a word:
Código:
// Necesario para alinear a Word el compilador
#pragma pack( push )
#pragma pack( 2 )
.....
......
........
// y luego dejarlo como estaba...
#pragma pack( pop )
Copilalo tal y como te lo pongo o puedes tener problemas al ejecutar. Muy posiblemente por esto SaveResIconToFile te devuelve false y no crea el icono. Son las jugarretas de los compiladores. Por defecto lo tendrás alineado a Quad Word eso quiere decir que una estructura que ocupe 3 Bytes la redondea a 8 Bytes y eso no siempre es lo que nos conviene.

Prueba como te digo, funciona.

Saludos.

Última edición por escafandra fecha: 19-12-2008 a las 18:01:25.
Responder Con Cita
  #26  
Antiguo 20-12-2008
_cero_ _cero_ is offline
Miembro
 
Registrado: abr 2007
Posts: 147
Poder: 18
_cero_ Va por buen camino
Talking

Pues estoy de vuelta, solo para agradecer ya que las funciones que dejo escafandra me van de maravilla, y me regresaban falso porque no encontraban el recurso, así que lo único que tuve que hacer es cambiar el Id de tipo int a tipo char, y así sí que jalo. ahora solo le estoy asiendo unas pequeñas modificaciones para que me dé el icono por su posición y no por su nombre (pero eso ya lo hago yo si no, no aprendo).
Responder Con Cita
  #27  
Antiguo 20-12-2008
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Me alegro de que lo consigas. No te olvides de postear tus soluciones, Siempre servirán a mas gente.

Saludos.
Responder Con Cita
  #28  
Antiguo 21-12-2008
_cero_ _cero_ is offline
Miembro
 
Registrado: abr 2007
Posts: 147
Poder: 18
_cero_ Va por buen camino
Thumbs up

Pues regreso para reportar mis avances y dejarles esta nueva función, en parte basada en las funciones que nos proporciono amablemente escafandra, solo que esta recorre todos los recursos del tipo icono y con un contador(numme), que es el que se encarga de identificar el icono que deseo extraer.
Código:
bool CALLBACK ResNameProc(HANDLE hModule, LPCTSTR lpType,LPTSTR lpszName,LONG lpName)
{
  if (numme==0) {
    HRSRC hRsrc = FindResource( hModule, MAKEINTRESOURCE(lpszName), lpType );
    HGLOBAL hGroup = LoadResource( hModule, hRsrc );
    GRPICONDIR * lpGrpIconDir = (LPGRPICONDIR)LockResource( hGroup );
    for( int i=0; i < lpGrpIconDir->idCount; ++i ) {
      int x = (i%7)*64;
      int y = (i/8)*64;
      GRPICONDIRENTRY * e = &lpGrpIconDir->idEntries[i];
      hRsrc = FindResource( hModule, MAKEINTRESOURCE( e->nID ), RT_ICON );
      HGLOBAL hGlobal = LoadResource( hModule, hRsrc );
      ICONIMAGE *lpIconImage = (LPICONIMAGE)LockResource( hGlobal );
      HICON hicon = CreateIconFromResourceEx(
        (PBYTE)lpIconImage,
        e->dwBytesInRes,
        TRUE,
        0x00030000,//DWORD dwVersion,
        e->bWidth,
        e->bHeight,
        0
      );
      TIcon *icon = new TIcon;
      icon->Handle = hicon;
      if (icon->Width==256) {
        lolol++; icon->SaveToFile("C:\\ico"+String(numme)+".ico");
      }
    };
  }
  return true;
}
Y se manda a llamar así
Código:
HMODULE hModule=LoadLibrary("C:\\ShowTime.exe");

EnumResourceNames(hModule,RT_GROUP_ICON,(ENUMRESNAMEPROC)ResNameProc,0);
  

FreeLibrary(hModule);
Como ven es muy similar a “EnumProcesses” lo que me facilito mas comprenderla, aunque en lo personal me gustaban mas las otras funciones solo que nunca pude extraer el icono según su posición, porque simplemente no me encontraba el icono o me marcaba que tenia mas imágenes de las que en realidad tenia. pero por si les sirve, para buscar por índice de recursos con “FindResource” solo se pone así

Código:
FindResource(hModule, 

"#1", //  1=posición en recursos (índice)
RT_ICON);
Bueno subiré la función completa(cuando la termine al 100), para extraer iconos de extensiones en alta resolución.

Última edición por _cero_ fecha: 21-12-2008 a las 06:21:01.
Responder Con Cita
  #29  
Antiguo 21-12-2008
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Bien _cero_. Ya que entraste en el tema de enumeración de los resources, te dejo esto:

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

typedef BOOL (__stdcall *TP)();

struct TResInGr{
   int Count;
   int Id;
   char* ResName;
   HRSRC hRes;
};

// Para la cuenta de elementos 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;
}
Saludos.


PD:
Una aclaración sobre las funciones que dejé anteriormente. El indice para encontrar el icono, como explico es un indice como si de una matriz se tratara. La Función FindResource que usan no es la API sino una nueva que añado en este post. Siento no haberme dado cuanta hasta ahora que no la había proporcionado, por eso no iban bien los índices. en las funciones posteadas.

Última edición por escafandra fecha: 21-12-2008 a las 14:18:36.
Responder Con Cita
  #30  
Antiguo 21-12-2008
_cero_ _cero_ is offline
Miembro
 
Registrado: abr 2007
Posts: 147
Poder: 18
_cero_ Va por buen camino
Arrow

Pues ya quedo, les dejo el código aquí para que lo descarguen, ya que la solución está formada por tres funciones muy extensas y me pareció mejor subir fuentes que escribir todo el código aquí. Nos vemos y gracias por su ayuda, en especial a escafandra.
Responder Con Cita
Respuesta



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
try-except - grandes problemas pmfras Conexión con bases de datos 1 12-06-2007 02:53:33
Obtener iconos para mejorar aspectos zugazua2001 Varios 2 05-08-2006 19:43:45
Grandes frases de grandes personas Nuria Humor 7 18-04-2004 05:40:17
tablas grandes Giniromero Firebird e Interbase 4 14-04-2004 18:18:48


La franja horaria es GMT +2. Ahora son las 12:07:05.


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