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
  #1  
Antiguo 18-12-2008
_cero_ _cero_ is offline
Miembro
 
Registrado: abr 2007
Posts: 147
Poder: 18
_cero_ Va por buen camino
Post

Pues miren logre conseguir un icono de 32x32, con el siguiente código.

función.
Código:
UINT ExtractIconEx(          
  LPCTSTR lpszFile,
  int nIconIndex,
  HICON *phiconLarge,
  HICON *phiconSmall,
  UINT nIcons
);
Y aquí está como la use.
Código:
HICON hIcon;
HICON hIconSmall;
ExtractIconEx("C:\\Windows\\System32\\calc.exe", 0, &hIcon, &hIconSmall,1);

Image1->Picture->Icon->Handle   = hIcon;//hIconSmall;
Quisiera unos iconos más grandes, pero aun no entiendo el rollo de los índices de los iconos (y creo que con esto se solucionaría todo), alguien me podría explicar algo sobre los índices de los iconos?.
Responder Con Cita
  #2  
Antiguo 18-12-2008
_cero_ _cero_ is offline
Miembro
 
Registrado: abr 2007
Posts: 147
Poder: 18
_cero_ Va por buen camino
Red face

Ya profundice mas en este tema, y me quedo claro que un exe o dll pueden tener más de un icono y el índice es el numero que identifica a cada icono, ahora bien como saben un icono puede tener barias imágenes dentro de este, así que mi pregunta es de cómo puedo accesar a estas imágenes que están dentro del icono.
Les dejo una imagen por si no queda claro de a que estoy intentando accesar.

http://www.subirimagenes.com/otros-captura-1646462.html
Responder Con Cita
  #3  
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
Cita:
Empezado por _cero_ Ver Mensaje
así que mi pregunta es de cómo puedo accesar a estas imágenes que están dentro del icono.
Quizás esto te pueda ayudar:

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;
}
o esta otra versión de la misma función:
Código:
//---------------------------------------------------------------------------
// Devuelve un ResMem Icon de un hModule
// Reserva la memoria necesaria y Requiere liberarla luego con
// VirtualFree(Mem, 0, MEM_RELEASE);
// Id: Indice del Grupo de iconos como si fuese una array comenzando por 0
void* ExtractResIconFromModule(HMODULE hModule, int Id)
{
    LPGRPICONDIR grpIconDir;
    LPGRPICONDIR grpSrcIconDir;
    LPGRPICONDIRENTRY grpIconEntry;
    LPICONIMAGE  grpIconImage;
    LPICONIMAGE  resIconImage;
    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) return 0;

    // Reservo memoria para la imagen del Icono en memoria
    BYTE* IconMem = (BYTE*)VirtualAlloc(0, AllSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

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

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

Pues muchas gracias escafandra, la función que dejaste se ve interesante, pero me gusto mas la idea que presentaste sobre obtener la dirección e índice del icono de una extensión desde el registro (muy buena idea, yo ni si quera sabia que se podía), así podría extraer y guardar los iconos que use en una especie de cache, y para obtener el tamaño de la imagen que quiero solo usaría el siguiente código.

Código:
Image1->Picture->Icon ->Handle=LoadImage(NULL, "C:\\txt.ico",
IMAGE_ICON, 128, 128,
LR_LOADFROMFILE | LR_CREATEDIBSECTION);
Lo intento de esta forma y les cuento.
Responder Con Cita
  #5  
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
Solo una cosa mas, esta forma de asignar la imagen del icono:
Código:
Image1->Picture->Icon ->Handle = hIcon;
Puede dar problemas con el nº de colores para algunas versiones de Builder antiguas. Funciona bien para iconos de 16 colores pero si tiene mas, se reducen, al menos en BCB 5 y 6. Me imagino que en delphi 5 y 6 pasará lo mismo. Creo que las versiones de 2008 no tienen este problema.

Para solventar este problema escribí una función que mapea un HICON en memoria según un HDC concreto.

Si en tu Builder 2007 no tienes ese problema, pues perfecto. Si es así dímelo.

Saludos.

PD:
La idea de cHackAll:
Cita:
Empezado por cHackAll Ver Mensaje
Tambien te tocara revisar la API ShellAPI.FindExecutable
Te puede servir para aquellos iconos desde su ejecutable, claro que lños que estén en el resource del mismo ejecutable. A mi me parece también una buena opción.

Última edición por escafandra fecha: 18-12-2008 a las 10:36:21.
Responder Con Cita
  #6  
Antiguo 18-12-2008
_cero_ _cero_ is offline
Miembro
 
Registrado: abr 2007
Posts: 147
Poder: 18
_cero_ Va por buen camino
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:\".
Responder Con Cita
  #7  
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
  #8  
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
_cero_ Estuve probando los índices en ExtractAssociatedIcon y no he obtenido el resultado deseado. Sólo devuelve un hIcon 32x32.

Cita:
Empezado por _cero_ Ver Mensaje
alguien me podría explicar algo sobre los índices de los iconos?.
Pues un icono, tanto en su versión file.ico como en su versión en memoria y resource, puede contener mas de una imagen de icono, es decir un grupo de iconos de distinto tamaño y número de colores. De esta forma se puede elegir el mas apropiado según el modo de video presente. Tienes información de esto aquí y en este hilo. Esto me hizo pensar que quizás ExtractAssociatedIcon permitiría escoger un icono... pero no funciona.

De todas formas he cotilleado SHELL32.dll con un editor de recursos y los iconos de 48x48 están, tiene muchos mas iconos que los que muestra cuando tratas de personalizar el icono mostrado por una carpeta, por ejemplo.

Bueno, ¿y si del Registro sacamos el default icon de un tipo de archivo?. Por ejemplo HKEY_CLASSES_ROOT\txtfile\DefaultIcon = %SystemRoot%\system32\shell32.dll,-152 se puede leer como un resource, 152 es el grupo de iconos correspondiente al notepad y archivos de extensión asociada a este programa. Basta leerlos y obtener el del tamaño que te interesa.

Claro, esta es una solución que puede funcionar muy bien pero es un poco trabajosa. He buscado en la Red y este problema lo ha encontrado mucha gente.... Quizas una búsqueda mas a fondo de con una solución mas simple.

Saludos.

Última edición por escafandra fecha: 18-12-2008 a las 23:34:10.
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 10:27:02.


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