Page 1 of 1

Icono pequeño

PostPosted: Fri Mar 28, 2014 11:34 am
by antolin
Hola foreros.

Tengo un pequeño problema: necesito un icono de Sell32.dll. Con extracticon() me devuelve el icono de 32X32, pero necesito el de 16X16. ¿alguna foma de elegir el tamaño del icono a extraer? Según parece extrae el icono del tamaño que especifique el correspondiente GetSysMetrics(). ¿Hay alguna forma de cambiar alguno de los parametros del conjunto de constante que devueve GetSysMetrics(), concretamente SM_CXICON y SM_CYICON?

Gracias

Icono pequeño (Solucionado)

PostPosted: Mon Mar 31, 2014 9:47 am
by antolin
Bueno, investigando y probando, me he dado cuenta que el culpable no es el ExtractIcon() sino el DrawIcon(). ExtractIcon() no solo extrae efectivamente el icono requerido, sino que extrae todos sus layers (distintos tamaños), sin embargo DrawIcon() lo pinta al tamaño SM_CXICON y SM_CYICON. Si quieres un tamaño diferente necesitas DrawIconEx() que tiene más flexibilidad de tamaños y colores que el parco DrawIcon().

Un saludo.

Re: Icono pequeño

PostPosted: Wed May 21, 2014 3:12 pm
by cuatecatl82
antolin:

Recurro a tu valiosa ayuda, tengo el mismo problema pero a la inversa, necesito dibijar un icono a 64*64, no encontre mucha documentación sobre el dato en el foro, pudiste convertir la funcion DrawIconEx()

Encontre estos enlaces pero no di con la conversión:
http://winapi.conclase.net/curso/?winfun=DrawIconEx
http://msdn.microsoft.com/en-us/library/windows/desktop/ms648065%28v=vs.85%29.aspx

Algun ejemplo de como sokucionaste este detalle..

Gracias..

Re: Icono pequeño

PostPosted: Fri Jun 27, 2014 4:49 pm
by antolin
Primero disculparme por la tardanza.

Lo que necesitas lo he medio solucionado de la siguiente manera:

Para extraer un icono de una DLL he implementado la función:

Code: Select all  Expand view
HB_FUNC( LOADDLLICON )  // LoadDllIcon( LPSTR IconResource, INT nSize )
   {
   HICON hIcon = LoadImage( GetResources(), IF(ISCHAR(1),hb_parc(1),MAKEINTRESOURCE(hb_parni(1))), IMAGE_ICON, hb_parni(2), hb_parni(2), LR_DEFAULTCOLOR ) ;

   hb_retnl( ( LONG ) hIcon ) ;
   }
 

Y hago:

Code: Select all  Expand view
SET RESOURCES TO cDLLFile
hIcon := LoadDllIcon( nIcon/cIcon, nSize )
SET RESOURCES TO

- cDLLFile es el fichero DLL que contiene el icono (preferiblemente con el path completo).
- nIcon o cIcon son el nombre del icono en la DLL, puede ser un número o un String.
- nSize es el tamaño que queremos. Si existe un icono con ese tamaño ese será el que devuelva la función, sino el más cercano en tamaño.
 

Para extraer el icono de un EXE implementé:

Code: Select all  Expand view
HB_FUNC( EXTRACTICOEX )  // ExtractIcoEx( LPSTR IconFile, BOOL lSmall, INT nIndex )
   {
   HICON aIcon[1] ;

   if ( hb_parl( 2 ) ) ExtractIconEx( hb_parc(1), hb_parni(3), 0, (HICON *) aIcon, 1) ;
   else            ExtractIconEx( hb_parc(1), hb_parni(3), (HICON *) aIcon, 0, 1) ;

   hb_retnl( ( LONG ) aIcon[0] ) ;
   }

 
Y hago:

Code: Select all  Expand view
nSize := xx
hIcon := ExtractIcoEx( cFile, nSize = 16, nIndex )

- cFile es el fichero del que queremos extraer el icono (preferiblemente con el path completo).
- nSize es el tamaño de icono que queremos.
- nIndex es el puesto que ocupa el icono en el fichero. Un 0 extrae el 1º icono, un 1 el 2º, etc. Por defecto coge 0.

 

Esta función no extrae el icono del tamaño específico, pero al menos, con nSize := 16, extrae el icono de 16X16; un nSize mayor, extrae al menos el de 32X32 que queda mejor ampliado a 48X48 que el de 16X16, es posible que exista otra función más adecuada, pero mi Borland C++ no la trae, o no la he encontrado.

Para pintar el icono al tamaño deseado, utilizo:

Code: Select all  Expand view
HB_FUNC( DRAWICONEX ) // DrawIconEx( hDc, nY, nX, hIcon, nSize )
   {
   DrawIconEx( (HDC) hb_parnl( 1 ), hb_parni( 3 ), hb_parni( 2 ), (HICON) _parnl( 4 ), hb_parni( 5 ), hb_parni( 5 ),0,0, DI_NORMAL ) ;
   }

- nY y nX Son la coordenadas donde quiero dibujarlo.
- hIcon es el handle del icono obtenido con alguna de las funciones anteriores.
- nSize es el tamaño al que quiero dibujarlo.
 

Con estos métodos, el icono de 16X16 siempre se puede conseguir (si existe); uno de mayor tamaño, no siempre, pero al menos siempre puedo pintarlo del tamaño deseado.

Espero te sea de utilidad.

Saludos.

Re: Icono pequeño

PostPosted: Fri Jun 27, 2014 9:42 pm
by cuatecatl82
Saludos y Gracias por el aporte..

Re: Icono pequeño

PostPosted: Mon Jul 14, 2014 4:02 pm
by antolin
Además de lo anterior he implementado otras tres funciones que a lo mejor te pueden ser de utilidad.

Code: Select all  Expand view
HB_FUNC( READICONFILE )  // ReadIconFile( LPSTR cFile, BOOL lSmall, BOOL lOpen )
   {
   SHFILEINFO sfi ;

   UINT uFlag = SHGFI_ICON + IF( hb_parl( 2 ), SHGFI_SMALLICON, SHGFI_LARGEICON ) + IF( hb_parl( 3 ), SHGFI_OPENICON, 0 ) + 0x000000020 ;
   
   ZeroMemory(&sfi, sizeof(SHFILEINFO) ) ;

   SHGetFileInfo( ( LPCTSTR ) hb_parc(1), 0, &sfi, sizeof(SHFILEINFO), uFlag  ) ;

   hb_retnl( ( LONG ) sfi.hIcon ) ;
   }
 
Esta función me devuelve el icono del fichero, carpeta, o dispositivo que Windows utiliza en su Shell.

- cFile es el nombre del fichero, Directorio o dispositivo; este último en formato "c:\".
- lSmall .T. si queremos el icono de 16X16, .F. el de ¿32X32?
- lOpen .T. si queremos el icono correspondiente a carpeta abierta. .F. la cerrada (según versión del Windows son iguales).

Code: Select all  Expand view
HB_FUNC( READTIPEFILE )  // ReadTipeFile( LPSTR cFile )
   {
   SHFILEINFO sfi ;

   ZeroMemory(&sfi, sizeof(SHFILEINFO) ) ;

   SHGetFileInfo( ( LPCTSTR ) hb_parc(1), 0, &sfi, sizeof(SHFILEINFO), SHGFI_TYPENAME   ) ;
   
   hb_retc( sfi.szTypeName ) ;
   }
 
Esta función devuelve la expresión "tipo de fichero" que Windows utiliza en su Shell.

- cFile es el nombre del fichero, Directorio o dispositivo; este último en formato "c:\".


Code: Select all  Expand view
HB_FUNC( READICONTIPEFILE ) // ReadIconTipeFile( LPSTR cFile, BOOL lSmall )
   {
   SHFILEINFO sfi ;

   UINT uFlag = SHGFI_ICON + IF( hb_parl( 2 ), SHGFI_SMALLICON, SHGFI_LARGEICON ) + SHGFI_TYPENAME + SHGFI_DISPLAYNAME ;

   ZeroMemory(&sfi, sizeof(SHFILEINFO) ) ;

   SHGetFileInfo( ( LPCTSTR ) hb_parc(1), 0, &sfi, sizeof(SHFILEINFO), uFlag  ) ;

   hb_reta(3) ;

   hb_stornl( ( LONG ) sfi.hIcon, -1, 1 ) ;
   hb_storc( sfi.szTypeName, -1, 2 ) ;
   hb_storc( sfi.szDisplayName, -1, 3 ) ;
   }
 

Esta función devuelve un array con 1-Icono, 2-Tipo, 3-Nombre del fichero, Directorio o dispositivo como aparece en el Shell de Windows.

- cFile es el nombre del fichero, Directorio o dispositivo; este último en formato "c:\".
- lSmall .T. si queremos el icono de 16X16, .F. el de ¿32X32?

Saludos.