Convertir un BMP en ICO
Y m�s...
Fecha: 03/Feb/99 (11/Ene/99)
Revisado el 09/Feb/99 (05/Feb/99)
�ltima revisi�n: 10/Feb/99
Autor: Eduardo A. Morcillo < [email protected]
>
Te envio un m�dulo con dos funciones que creo
que son utiles.
La primera es para crear objetos StdPicture a partir de handles de iconos, bitmaps o
metafiles.
La segunda crea iconos (en objetos StdPicture) a partir de bitmaps en objetos StdPicture.
El codigo esta bastante comentado. La primera funcion la he sacado del Knowledge Base de
Microsoft y la segunda esta hecha 100% por mi.
Eduardo.
Revisi�n del 10/02/1999:
He separado las distintas conversiones en diferentes procedimientos para hacer mas claro
el c�digo. He tambi�n agregado un nuevo parametro MaskColor para especificar el color
que sera usado como transparente por el icono.
He intentado hacer que el subprocedimiento pvWMFaICO funcione, pero no he tenido exito con
las funciones para metafiles. Si alguien sabe o pudo usarlas me gustaria que me pasaran el
codigo la manera.
Eduardo
Actualizacion del 05/02/1999:
Corregi algunos errores como que si no se podia crear el objeto el handle del icono
quedaba en memoria.
A�ad� soporte para iconos. Si la funcion recibe un icono devuelve un nuevo icono con el
tama�o especificado en la funcion.
En cuanto a esto ultimo si intentan grabar con SavePicture un icono de tama�o diferente a
32x32 la transparencia no es grabada correctamente. No es problema del codigo. Supongo que
es un bug en la function SavePicture o esta no soporta iconos que no sean 32x32, ya que
esos son los unicos que VB usa.
Eduardo.
El c�digo:
Attribute VB_Name = "mdlPictureAIcono" Option Explicit Public Enum ModosDeStretch BlackOnWhite = 1 WhiteOnBlack = 2 ColorOnColor = 3 Halftone = 4 Desconocida = 5 End Enum Private Type PICTDESC cbSizeOfStruct As Long picType As Long hgdiObj As Long hPalOrXYExt As Long End Type Private Type IID Data1 As Long Data2 As Integer Data3 As Integer Data4(0 To 7) As Byte End Type Private Declare Sub OleCreatePictureIndirect Lib "oleaut32.dll" (lpPictDesc As PICTDESC, riid As IID, ByVal fOwn As Boolean, lplpvObj As Object) Private Type pvICONINFO fIcon As Long xHotspot As Long yHotspot As Long hbmMask As Long hbmColor As Long End Type Private Type pvRECT Left As Long Top As Long Right As Long Bottom As Long End Type Private Declare Function CreateIconIndirect Lib "user32" (piconinfo As pvICONINFO) As Long Private Declare Function DestroyIcon Lib "user32" (ByVal hIcon As Long) As Long Private Declare Function DrawIconEx Lib "user32" (ByVal hdc As Long, ByVal xLeft As Long, ByVal yTop As Long, ByVal hIcon As Long, ByVal cxWidth As Long, ByVal cyWidth As Long, ByVal istepIfAniCur As Long, ByVal hbrFlickerFreeDraw As Long, ByVal diFlags As Long) As Long Private Declare Function GetIconInfo Lib "user32" (ByVal hIcon As Long, piconinfo As pvICONINFO) As Long Private Declare Function CreateBitmap Lib "gdi32" (ByVal nWidth As Long, ByVal nHeight As Long, ByVal nPlanes As Long, ByVal nBitCount As Long, lpBits As Any) As Long Private Declare Function SetStretchBltMode Lib "gdi32" (ByVal hdc As Long, ByVal nStretchMode As Long) As Long Private Declare Function StretchBlt Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal XSrc As Long, ByVal YSrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal dwRop As Long) As Long Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal XSrc As Long, ByVal YSrc As Long, ByVal dwRop As Long) As Long Private Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long Private Declare Function CreateSolidBrush Lib "gdi32" (ByVal crColor As Long) As Long Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hdc As Long) As Long Private Declare Function GetWindowDC Lib "user32" (ByVal hwnd As Long) As Long Private Declare Function FillRect Lib "user32" (ByVal hdc As Long, lppvRECT As pvRECT, ByVal hBrush As Long) As Long Private Declare Function SelectPalette Lib "gdi32" (ByVal hdc As Long, ByVal hPalette As Long, ByVal bForceBackground As Long) As Long Private Declare Function RealizePalette Lib "gdi32" (ByVal hdc As Long) As Long Private Declare Function CreateHalftonePalette Lib "gdi32" (ByVal hdc As Long) As Long Private Declare Function GetSysColor Lib "user32" (ByVal nIndex As Long) As Long Private Declare Function OleTranslateColor Lib "oleaut32.dll" (ByVal lOleColor As Long, ByVal lHPalette As Long, lColorRef As Long) As Long Private Declare Function SetBkColor Lib "gdi32" (ByVal hdc As Long, ByVal Color As Long) As Long Private Declare Function SetTextColor Lib "gdi32" (ByVal hdc As Long, ByVal Color As Long) As Long Const DI_MASK = &H1 Const DI_IMAGE = &H2 '--------------------------------------------------------------------------- ' GetIcon: devuelve un icono pasado cualquier clase de objeto Picture. ' ' Parametros: ' Bitmap: el objeto Picture a convertir en ICO ' [IconCX]: el ancho del icono a crear ' [IconCY]: el alto del icono a crear ' [ModoDeStretch]: la manera en que windows cambiara el tama�o de ' la imagen ' [CrearCursor]: crea un cursor en lugar de un icono ' [MaskColor]: especifica el color que se usara para dar transparencia al ' icono. Solo se usa si el objeto original es un mapa de bits. '--------------------------------------------------------------------------- Public Function GetIcon(ByVal Bitmap As IPicture, Optional ByVal IconCX As Long, Optional ByVal IconCY As Long, Optional ModoDeStretch As ModosDeStretch = Halftone, Optional CrearCursor As Boolean = False, Optional MaskColor As OLE_COLOR = -1) As StdPicture Dim hIcon As Long, IconPict As StdPicture Dim ScreenDC As Long, BitmapDC As Long Dim hMask As Long, hImagen As Long Dim hIcn As Long, II As pvICONINFO On Error Resume Next ' Si no se indica un tama_o de icono ' se crea uno de 32x32 If IconCX = 0 Then IconCX = 32 If IconCY = 0 Then IconCY = 32 ScreenDC = GetWindowDC(0&) BitmapDC = CreateCompatibleDC(ScreenDC) hImagen = CreateCompatibleBitmap(ScreenDC, IconCX, IconCY) hMask = CreateBitmap(IconCX, IconCY, 1, 1, ByVal 0&) If Bitmap Is Nothing Then pvIconoVacio IconCX, IconCY, hImagen, hMask, BitmapDC ElseIf Bitmap.Handle = 0 Then pvIconoVacio IconCX, IconCY, hImagen, hMask, BitmapDC ElseIf Bitmap.Type = vbPicTypeEMetafile Or Bitmap.Type = vbPicTypeMetafile Then pvWMFaICO IconCX, IconCY, hImagen, hMask, BitmapDC ElseIf Bitmap.Type = vbPicTypeIcon Then pvResizeIcon Bitmap, IconCX, IconCY, hImagen, hMask, BitmapDC Else pvBMPaICO Bitmap, IconCX, IconCY, hImagen, hMask, BitmapDC, ScreenDC, MaskColor, ModoDeStretch End If DeleteDC BitmapDC ReleaseDC 0&, ScreenDC II.fIcon = CrearCursor II.hbmColor = hImagen II.hbmMask = hMask hIcon = CreateIconIndirect(II) Set IconPict = HandleToPicture(hIcon, vbPicTypeIcon) If IconPict Is Nothing Then DeleteObject hIcn Set GetIcon = Nothing Else Set GetIcon = IconPict End If End Function Private Sub pvBMPaICO(Bitmap As IPicture, ByVal Ancho As Long, ByVal Alto As Long, ByVal hImagen As Long, ByVal hMask As Long, ByVal hdc As Long, ByVal ScrDC As Long, ByVal MaskColor As Long, ByVal ModoDeStretch As Byte) Dim R As pvRECT, hBr As Long, MskClr As Long Dim hOldPal As Long, hDC_Bitmap As Long, hDC_Copia As Long Dim TmpBMP As Long R.Bottom = Alto R.Right = Ancho ' Creo un segudo DC para usar ' en caso de que la imagen ' no este seleccionada en uno hDC_Bitmap = CreateCompatibleDC(ScrDC) SetStretchBltMode hdc, ModoDeStretch ' Dibujo la mascara If MaskColor = -1 Then ' No hay transparencia ' Selecciono la mascara... SelectObject hdc, hMask ' ... y la lleno con negro (opaco) hBr = CreateSolidBrush(&H0) FillRect hdc, R, hBr DeleteObject hBr ' Selecciono la imagen SelectObject hdc, hImagen ' y pinto el bitmap If Bitmap.CurDC = 0 Then SelectObject hDC_Bitmap, Bitmap.Handle StretchBlt hdc, 0, 0, Ancho, Alto, hDC_Bitmap, 0, 0, Bitmap.Width / 26.45, Bitmap.Height / 26.45, vbSrcCopy Else StretchBlt hdc, 0, 0, Ancho, Alto, Bitmap.CurDC, 0, 0, Bitmap.Width / 26.45, Bitmap.Height / 26.45, vbSrcCopy End If Else ' Creo un DC y un bitmap para ' copiar la imagen. Esto lo ' debo hacer porque si el bitmap ' es DIB no pasa a B&N usando ' los colores de fondo y texto. hDC_Copia = CreateCompatibleDC(ScrDC) SetStretchBltMode hDC_Copia, ModoDeStretch TmpBMP = CreateCompatibleBitmap(ScrDC, Ancho, Alto) ' Hago la copia del bitmap SelectObject hDC_Copia, TmpBMP If Bitmap.CurDC = 0 Then SelectObject hDC_Bitmap, Bitmap.Handle StretchBlt hDC_Copia, 0, 0, Ancho, Alto, hDC_Bitmap, 0, 0, Bitmap.Width / 26.45, Bitmap.Height / 26.45, vbSrcCopy Else StretchBlt hDC_Copia, 0, 0, Ancho, Alto, Bitmap.CurDC, 0, 0, Bitmap.Width / 26.45, Bitmap.Height / 26.45, vbSrcCopy End If ' De ahora en mas utilizo la copia ' de la que ya a sido modificado su ' tama~o ' ---- Creo la mascara ----- ' Selecciono la mascara en el DC SelectObject hdc, hMask ' Selecciona la paleta del bitmap hOldPal = SelectPalette(hdc, Bitmap.hPal, True) RealizePalette hdc ' Paso el OLE_COLOR a clrref OleTranslateColor MaskColor, Bitmap.hPal, MskClr ' Seteo el color de fondo con ' el color de mascara. SetBkColor hDC_Copia, MskClr SetTextColor hDC_Copia, vbWhite ' Al copiar windows transforma en blanco ' todos los pixel con el color de fondo ' y en negro el resto BitBlt hdc, 0, 0, Ancho, Alto, hDC_Copia, 0, 0, vbSrcCopy SelectPalette hdc, hOldPal, True SelectObject hdc, hImagen SelectObject hDC_Copia, hMask SelectObject hDC_Bitmap, TmpBMP hBr = CreateSolidBrush(&H0) FillRect hdc, R, hBr DeleteObject hBr ' Copio la mascara y luego la imagen BitBlt hdc, 0, 0, Ancho, Alto, hDC_Copia, 0, 0, vbNotSrcCopy BitBlt hdc, 0, 0, Ancho, Alto, hDC_Bitmap, 0, 0, vbSrcAnd SelectObject hDC_Bitmap, 0& SelectObject hDC_Copia, 0& SelectObject hdc, 0& DeleteObject TmpBMP DeleteDC hDC_Copia End If DeleteDC hDC_Bitmap End Sub Private Sub pvIconoVacio(ByVal Ancho As Long, ByVal Alto As Long, ByVal hImagen As Long, ByVal hMask As Long, ByVal hdc As Long) Dim R As pvRECT, hBr As Long R.Right = Ancho R.Bottom = Alto ' Dibujo la mascara SelectObject hdc, hMask hBr = CreateSolidBrush(&HFFFFFF) FillRect hdc, R, hBr DeleteObject hBr ' Dibujo la imagen SelectObject hdc, hImagen hBr = CreateSolidBrush(&H0) FillRect hdc, R, hBr DeleteObject hBr SelectObject hdc, 0& End Sub Private Sub pvWMFaICO(ByVal Ancho As Long, ByVal Alto As Long, ByVal hImagen As Long, ByVal hMask As Long, ByVal hdc As Long) ' Aqui deberia pasarse de WMF a ICO ' pero todavia no he podido hacerlo. pvIconoVacio Ancho, Alto, hImagen, hMask, hdc End Sub Private Sub pvResizeIcon(Icono As StdPicture, ByVal Ancho As Long, ByVal Alto As Long, ByVal hImagen As Long, ByVal hMask As Long, ByVal hdc As Long) ' Dibujo la mascara SelectObject hdc, hMask DrawIconEx hdc, 0, 0, Icono.Handle, Ancho, Alto, 0, 0, DI_MASK ' Dibujo la imagen SelectObject hdc, hImagen DrawIconEx hdc, 0, 0, Icono.Handle, Ancho, Alto, 0, 0, DI_IMAGE SelectObject hdc, 0& End Sub '--------------------------------------------------------------------------- ' HandleToPicture: Crea un objeto StdPicture dado un handle de bitmap, icono ' o metafile. '--------------------------------------------------------------------------- Public Function HandleToPicture(ByVal hGDIHandle As Long, ByVal ObjectType As PictureTypeConstants, Optional ByVal hPal As Long = 0) As StdPicture Dim ipic As IPicture, picdes As PICTDESC, iidIPicture As IID ' Fill picture description picdes.cbSizeOfStruct = Len(picdes) picdes.picType = ObjectType picdes.hgdiObj = hGDIHandle picdes.hPalOrXYExt = hPal ' IPictureDisp {7BF80981-BF32-101A-8BBB-00AA00300CAB} iidIPicture.Data1 = &H7BF80981 iidIPicture.Data2 = &HBF32 iidIPicture.Data3 = &H101A iidIPicture.Data4(0) = &H8B iidIPicture.Data4(1) = &HBB iidIPicture.Data4(2) = &H0 iidIPicture.Data4(3) = &HAA iidIPicture.Data4(4) = &H0 iidIPicture.Data4(5) = &H30 iidIPicture.Data4(6) = &HC iidIPicture.Data4(7) = &HAB ' Crea el objeto con el handle OleCreatePictureIndirect picdes, iidIPicture, True, ipic Set HandleToPicture = ipic End Function