I need to quickly render a large number of small pictures in my grid cells, and the pictures need to be transparent to the grid backcolor. I'm ready to use the following code to achieve my purpose, I'd like to know if there is a simpler, more efficient way.

I know that AlphaBlend (msimg32) and GdiAlphaBlend (gdi32.dll) can do similar work. In addition, I also know that LaVolpe's stdPicEx2 can achieve this functionality, but stdPicEx2 is too large for my grid control, and I'm not familiar with GdiPlus. I wonder if I can use gdi32 or Cairo to simply and quickly render pictures in grid cells.Code:`Private Sub DrawPicture(lpRect As RECT, Optional lBrushColor As Long = -1)`

'****************************************************************************

' draw the picture by calling the TransBlt routines *

'****************************************************************************

Dim tmpMaskColor As Long

' --Draw picture

If tmppic.Type = vbPicTypeIcon Then

tmpMaskColor = TranslateColor(&HC0C0C0)

Else

tmpMaskColor = m_nMaskColor

End If

If Is32BitBMP(tmppic) Then

TransBlt32 hDC, lpRect.Left, lpRect.Top, PicW, PicH, tmppic, lBrushColor

Else

TransBlt hDC, lpRect.Left, lpRect.Top, PicW, PicH, tmppic, tmpMaskColor, lBrushColor

End If

End Sub

Private Sub TransBlt32(ByVal DstDC As Long, ByVal dstX As Long, ByVal dstY As Long, ByVal DstW As Long, ByVal DstH As Long, ByVal SrcPic As StdPicture, Optional ByVal BrushColor As Long = -1, Optional ByVal isGreyscale As Boolean = False)

'****************************************************************************

'* Routine : Renders 32 bit Bitmap *

'* Author : Dana Seaman *

'****************************************************************************

Dim b As Long, H As Long, f As Long, i As Long, newW As Long

Dim TmpDC As Long, TmpBmp As Long, TmpObj As Long

Dim Sr2DC As Long, Sr2Bmp As Long, Sr2Obj As Long

Dim DataDest() As RGBQUAD, DataSrc() As RGBQUAD

Dim Info As BITMAPINFO, BrushRGB As RGBQUAD, gCol As Long

Dim hOldOb As Long, PicEffect As enumPicEffect

Dim SrcDC As Long, tObj As Long, ttt As Long

Dim bDisOpacity As Byte

Dim OverOpacity As Byte

Dim a2 As Long

Dim a1 As Long

If DstW = 0 Or DstH = 0 Then Exit Sub

If SrcPic Is Nothing Then Exit Sub

If m_ButtonState = eStateOver Then

PicEffect = m_PicEffectonOver

ElseIf m_ButtonState = eStateDown Then

PicEffect = m_PicEffectonDown

End If

If Not m_bEnabled Then

Select Case m_PicDisabledMode

Case edpBlended

bDisOpacity = 52

Case edpGrayed

bDisOpacity = m_PictureOpacity * 0.75

isGreyscale = True

End Select

End If

If m_ButtonState = eStateOver Then

OverOpacity = m_PicOpacityOnOver

End If

SrcDC = CreateCompatibleDC(hDC)

If DstW < 0 Then DstW = UserControl.ScaleX(SrcPic.Width, 8, UserControl.ScaleMode)

If DstH < 0 Then DstH = UserControl.ScaleY(SrcPic.Height, 8, UserControl.ScaleMode)

tObj = SelectObject(SrcDC, SrcPic)

TmpDC = CreateCompatibleDC(SrcDC)

Sr2DC = CreateCompatibleDC(SrcDC)

TmpBmp = CreateCompatibleBitmap(DstDC, DstW, DstH)

Sr2Bmp = CreateCompatibleBitmap(DstDC, DstW, DstH)

TmpObj = SelectObject(TmpDC, TmpBmp)

Sr2Obj = SelectObject(Sr2DC, Sr2Bmp)

With Info.bmiHeader

.biSize = Len(Info.bmiHeader)

.biWidth = DstW

.biHeight = DstH

.biPlanes = 1

.biBitCount = 32

.biSizeImage = 4 * ((DstW * .biBitCount + 31) \ 32) * DstH

End With

ReDim DataDest(Info.bmiHeader.biSizeImage - 1)

ReDim DataSrc(UBound(DataDest))

BitBlt TmpDC, 0, 0, DstW, DstH, DstDC, dstX, dstY, vbSrcCopy

BitBlt Sr2DC, 0, 0, DstW, DstH, SrcDC, 0, 0, vbSrcCopy

GetDIBits TmpDC, TmpBmp, 0, DstH, DataDest(0), Info, 0

GetDIBits Sr2DC, Sr2Bmp, 0, DstH, DataSrc(0), Info, 0

If BrushColor <> -1 Then

BrushRGB.rgbBlue = (BrushColor \ &H10000) Mod &H100

BrushRGB.rgbGreen = (BrushColor \ &H100) Mod &H100

BrushRGB.rgbRed = BrushColor And &HFF

End If

newW = DstW - 1

For H = 0 To DstH - 1

f = H * DstW

For b = 0 To newW

i = f + b

If m_bEnabled Then

If m_ButtonState = eStateOver Then

a1 = (CLng(DataSrc(i).rgbAlpha) * OverOpacity) \ 255

Else

a1 = (CLng(DataSrc(i).rgbAlpha) * m_PictureOpacity) \ 255

End If

Else

a1 = (CLng(DataSrc(i).rgbAlpha) * bDisOpacity) \ 255

End If

a2 = 255 - a1

With DataDest(i)

If BrushColor <> -1 Then

If a1 = 255 Then

DataDest(i) = BrushRGB

ElseIf a1 > 0 Then

.rgbRed = (a2 * .rgbRed + a1 * BrushRGB.rgbRed) \ 256

.rgbGreen = (a2 * .rgbGreen + a1 * BrushRGB.rgbGreen) \ 256

.rgbBlue = (a2 * .rgbBlue + a1 * BrushRGB.rgbBlue) \ 256

End If

Else

If isGreyscale Then

gCol = CLng(DataSrc(i).rgbRed * 0.3) + DataSrc(i).rgbGreen * 0.59 + DataSrc(i).rgbBlue * 0.11

If a1 = 255 Then

.rgbRed = gCol: .rgbGreen = gCol: .rgbBlue = gCol

ElseIf a1 > 0 Then

.rgbRed = (a2 * .rgbRed + a1 * gCol) \ 256

.rgbGreen = (a2 * .rgbGreen + a1 * gCol) \ 256

.rgbBlue = (a2 * .rgbBlue + a1 * gCol) \ 256

End If

Else

If a1 = 255 Then

If (PicEffect = epeLighter) Then

.rgbRed = aLighten(DataSrc(i).rgbRed)

.rgbGreen = aLighten(DataSrc(i).rgbGreen)

.rgbBlue = aLighten(DataSrc(i).rgbBlue)

ElseIf PicEffect = epeDarker Then

.rgbRed = aDarken(DataSrc(i).rgbRed)

.rgbGreen = aDarken(DataSrc(i).rgbGreen)

.rgbBlue = aDarken(DataSrc(i).rgbBlue)

Else

DataDest(i) = DataSrc(i)

End If

ElseIf a1 > 0 Then

If (PicEffect = epeLighter) Then

.rgbRed = (a2 * .rgbRed + a1 * aLighten(DataSrc(i).rgbRed)) \ 256

.rgbGreen = (a2 * .rgbGreen + a1 * aLighten(DataSrc(i).rgbGreen)) \ 256

.rgbBlue = (a2 * .rgbBlue + a1 * aLighten(DataSrc(i).rgbBlue)) \ 256

ElseIf PicEffect = epeDarker Then

.rgbRed = (a2 * .rgbRed + a1 * aDarken(DataSrc(i).rgbRed)) \ 256

.rgbGreen = (a2 * .rgbGreen + a1 * aDarken(DataSrc(i).rgbGreen)) \ 256

.rgbBlue = (a2 * .rgbBlue + a1 * aDarken(DataSrc(i).rgbBlue)) \ 256

Else

.rgbRed = (a2 * .rgbRed + a1 * DataSrc(i).rgbRed) \ 256

.rgbGreen = (a2 * .rgbGreen + a1 * DataSrc(i).rgbGreen) \ 256

.rgbBlue = (a2 * .rgbBlue + a1 * DataSrc(i).rgbBlue) \ 256

End If

End If

End If

End If

End With

Next b

Next H

' /--Paint it!

SetDIBitsToDevice DstDC, dstX, dstY, DstW, DstH, 0, 0, 0, DstH, DataDest(0), Info, 0

Erase DataDest, DataSrc

DeleteObject SelectObject(TmpDC, TmpObj)

DeleteObject SelectObject(Sr2DC, Sr2Obj)

If SrcPic.Type = vbPicTypeIcon Then DeleteObject SelectObject(SrcDC, tObj)

DeleteDC TmpDC

DeleteDC Sr2DC

DeleteObject tObj

DeleteDC SrcDC

End Sub

Private Sub TransBlt(ByVal DstDC As Long, ByVal dstX As Long, ByVal dstY As Long, ByVal DstW As Long, ByVal DstH As Long, ByVal SrcPic As StdPicture, Optional ByVal TransColor As Long = -1, Optional ByVal BrushColor As Long = -1, Optional ByVal MonoMask As Boolean = False, Optional ByVal isGreyscale As Boolean = False)

'****************************************************************************

'* Routine : To make transparent and grayscale images

'* Author : Gonkuchi

'

'* Modified by Dana Seaman

'****************************************************************************

Dim b As Long, H As Long, f As Long, i As Long, newW As Long

Dim TmpDC As Long, TmpBmp As Long, TmpObj As Long

Dim Sr2DC As Long, Sr2Bmp As Long, Sr2Obj As Long

Dim DataDest() As RGBTRIPLE, DataSrc() As RGBTRIPLE

Dim Info As BITMAPINFO, BrushRGB As RGBTRIPLE, gCol As Long

Dim hOldOb As Long, PicEffect As enumPicEffect

Dim SrcDC As Long, tObj As Long, ttt As Long

Dim bDisOpacity As Byte

Dim OverOpacity As Byte

Dim a2 As Long

Dim a1 As Long

If DstW = 0 Or DstH = 0 Then Exit Sub

If SrcPic Is Nothing Then Exit Sub

If m_ButtonState = eStateOver Then

PicEffect = m_PicEffectonOver

ElseIf m_ButtonState = eStateDown Then

PicEffect = m_PicEffectonDown

End If

If Not m_bEnabled Then

Select Case m_PicDisabledMode

Case edpBlended

bDisOpacity = 52

Case edpGrayed

bDisOpacity = m_PictureOpacity * 0.75

isGreyscale = True

End Select

End If

If m_ButtonState = eStateOver Then

OverOpacity = m_PicOpacityOnOver

End If

SrcDC = CreateCompatibleDC(hDC)

If DstW < 0 Then DstW = UserControl.ScaleX(SrcPic.Width, 8, UserControl.ScaleMode)

If DstH < 0 Then DstH = UserControl.ScaleY(SrcPic.Height, 8, UserControl.ScaleMode)

If SrcPic.Type = vbPicTypeBitmap Then 'check if it's an icon or a bitmap

tObj = SelectObject(SrcDC, SrcPic)

Else

Dim hBrush As Long

tObj = SelectObject(SrcDC, CreateCompatibleBitmap(DstDC, DstW, DstH))

hBrush = CreateSolidBrush(TransColor)

DrawIconEx SrcDC, 0, 0, SrcPic.handle, DstW, DstH, 0, hBrush, DI_NORMAL

DeleteObject hBrush

End If

TmpDC = CreateCompatibleDC(SrcDC)

Sr2DC = CreateCompatibleDC(SrcDC)

TmpBmp = CreateCompatibleBitmap(DstDC, DstW, DstH)

Sr2Bmp = CreateCompatibleBitmap(DstDC, DstW, DstH)

TmpObj = SelectObject(TmpDC, TmpBmp)

Sr2Obj = SelectObject(Sr2DC, Sr2Bmp)

ReDim DataDest(DstW * DstH * 3 - 1)

ReDim DataSrc(UBound(DataDest))

With Info.bmiHeader

.biSize = Len(Info.bmiHeader)

.biWidth = DstW

.biHeight = DstH

.biPlanes = 1

.biBitCount = 24

End With

BitBlt TmpDC, 0, 0, DstW, DstH, DstDC, dstX, dstY, vbSrcCopy

BitBlt Sr2DC, 0, 0, DstW, DstH, SrcDC, 0, 0, vbSrcCopy

GetDIBits TmpDC, TmpBmp, 0, DstH, DataDest(0), Info, 0

GetDIBits Sr2DC, Sr2Bmp, 0, DstH, DataSrc(0), Info, 0

If BrushColor > 0 Then

BrushRGB.rgbBlue = (BrushColor \ &H10000) Mod &H100

BrushRGB.rgbGreen = (BrushColor \ &H100) Mod &H100

BrushRGB.rgbRed = BrushColor And &HFF

End If

' --No Maskcolor to use

If Not m_bUseMaskColor Then TransColor = -1

newW = DstW - 1

For H = 0 To DstH - 1

f = H * DstW

For b = 0 To newW

i = f + b

If m_ButtonState = eStateOver Then

a1 = OverOpacity

Else

a1 = IIf(m_bEnabled, m_PictureOpacity, bDisOpacity)

End If

a2 = 255 - a1

If GetNearestColor(hDC, CLng(DataSrc(i).rgbRed) + 256& * DataSrc(i).rgbGreen + 65536 * DataSrc(i).rgbBlue) <> TransColor Then

With DataDest(i)

If BrushColor > -1 Then

If MonoMask Then

If (CLng(DataSrc(i).rgbRed) + DataSrc(i).rgbGreen + DataSrc(i).rgbBlue) <= 384 Then DataDest(i) = BrushRGB

Else

If a1 = 255 Then

DataDest(i) = BrushRGB

ElseIf a1 > 0 Then

.rgbRed = (a2 * .rgbRed + a1 * BrushRGB.rgbRed) \ 256

.rgbGreen = (a2 * .rgbGreen + a1 * BrushRGB.rgbGreen) \ 256

.rgbBlue = (a2 * .rgbBlue + a1 * BrushRGB.rgbBlue) \ 256

End If

End If

Else

If isGreyscale Then

gCol = CLng(DataSrc(i).rgbRed * 0.3) + DataSrc(i).rgbGreen * 0.59 + DataSrc(i).rgbBlue * 0.11

If a1 = 255 Then

.rgbRed = gCol: .rgbGreen = gCol: .rgbBlue = gCol

ElseIf a1 > 0 Then

.rgbRed = (a2 * .rgbRed + a1 * gCol) \ 256

.rgbGreen = (a2 * .rgbGreen + a1 * gCol) \ 256

.rgbBlue = (a2 * .rgbBlue + a1 * gCol) \ 256

End If

Else

If a1 = 255 Then

If PicEffect = epeLighter Then

.rgbRed = aLighten(DataSrc(i).rgbRed)

.rgbGreen = aLighten(DataSrc(i).rgbGreen)

.rgbBlue = aLighten(DataSrc(i).rgbBlue)

ElseIf PicEffect = epeDarker Then

.rgbRed = aDarken(DataSrc(i).rgbRed)

.rgbGreen = aDarken(DataSrc(i).rgbGreen)

.rgbBlue = aDarken(DataSrc(i).rgbBlue)

Else

DataDest(i) = DataSrc(i)

End If

ElseIf a1 > 0 Then

If (PicEffect = epeLighter) Then

.rgbRed = (a2 * .rgbRed + a1 * aLighten(DataSrc(i).rgbRed)) \ 256

.rgbGreen = (a2 * .rgbGreen + a1 * aLighten(DataSrc(i).rgbGreen)) \ 256

.rgbBlue = (a2 * .rgbBlue + a1 * aLighten(DataSrc(i).rgbBlue)) \ 256

ElseIf PicEffect = epeDarker Then

.rgbRed = (a2 * .rgbRed + a1 * aDarken(DataSrc(i).rgbRed)) \ 256

.rgbGreen = (a2 * .rgbGreen + a1 * aDarken(DataSrc(i).rgbGreen)) \ 256

.rgbBlue = (a2 * .rgbBlue + a1 * aDarken(DataSrc(i).rgbBlue)) \ 256

Else

.rgbRed = (a2 * .rgbRed + a1 * DataSrc(i).rgbRed) \ 256

.rgbGreen = (a2 * .rgbGreen + a1 * DataSrc(i).rgbGreen) \ 256

.rgbBlue = (a2 * .rgbBlue + a1 * DataSrc(i).rgbBlue) \ 256

End If

End If

End If

End If

End With

End If

Next b

Next H

' /--Paint it!

SetDIBitsToDevice DstDC, dstX, dstY, DstW, DstH, 0, 0, 0, DstH, DataDest(0), Info, 0

Erase DataDest, DataSrc

DeleteObject SelectObject(TmpDC, TmpObj)

DeleteObject SelectObject(Sr2DC, Sr2Obj)

If SrcPic.Type = vbPicTypeIcon Then DeleteObject SelectObject(SrcDC, tObj)

DeleteDC TmpDC

DeleteDC Sr2DC

DeleteObject tObj

DeleteDC SrcDC

End Sub

Any advice and suggestions would be greatly appreciated.