I was asking about transparent GIFs earlier, and sure enough, the next day, I found this in a Win32 GDI book I just bought. The example was in C++, but I decided to "assemblize" it here.

I'd imagine this version is sort of slow, since it re-generates the mask on every call. A better approach might be to split out the mask generating code and have the caller manage the mask DC.

Take a look and tell me what you think.
transBlt	PROTO	:DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :COLORREF


;yes, that's 11 parameters.

transBlt PROC hdcDest:DWORD, destX:DWORD, destY:DWORD, destW:DWORD, destH:DWORD, \
hdcSrc:DWORD, srcX:DWORD, srcY:DWORD, srcW:DWORD, srcH:DWORD, \
transColor:COLORREF

LOCAL hMemDC:HDC, hMask:HBITMAP, hOld:HBITMAP, maskWidth:DWORD, maskHeight:DWORD \
rect:RECT<>, oldBK:COLORREF, oldFG:COLORREF

; first, create a mask based on the source image and the transparency color

mov eax, srcX
mov rect.left, eax
add eax, srcW
mov rect.right, eax
mov eax, srcY
mov rect.top, eax
add eax, srcH
mov rect.bottom, eax

invoke LPtoDP, hSrcDC, ADDR rect, 2

mov eax, rect.right
sub eax, rect.left
.IF eax < 0
neg eax
.ENDIF
mov maskWidth, eax

mov eax, rect.bottom
sub eax, rect.top
.IF eax < 0
neg eax
.ENDIF
mov maskHeight, eax

invoke CreateCompatibleBitmap, hSrcDC
mov hMemDC, eax
invoke CreateBitmap, maskWidth, maskHeight, 1, 1, NULL
mov hMask, eax
invoke SelectObject, hMemDC, hMask
mov hOld, eax

invoke SetBkColor, hSrcDC, transColor
mov oldBK, eax

invoke StretchBlt, hMemDC, 0, 0, maskWidth, maskHeight, hSrcDC, srcX, srcY, srcW, srcH, SRCCOPY

invoke SetBkColor, hSrcDC, oldBK

; next xor the soucre onto the destionation.

invoke StretchBlt, hdcDest, destX, destY, destW, destH, hdcSrc, srcX, srcY, srcW, srcH, SRCINVERT

; then apply the mask, which will erase the area where the image needs to go.

RGB(0,0,0)
invoke SetTextColor, hdcDest, eax
mov oldFG, eax
RGB(255,255,255)
invoke SetBkColor, hdcDest, eax
mov oldBK, eax

invoke StretchBlt, hdcDest, destX, destY, destW, destH, hMemDC, 0, 0, maskWidth, maskHeight, SRCAND

invoke SetTextColor, hdcDest, oldFG
invoke SetBkColor, hdcDest, oldBK

; finally, xor the source image again erasing the transparent parts and putting the
; rest of the image into the "hole" left by the mask.

invoke StretchBlt, hdcDest, destX, destY, destW, destH, hdcSrc, srcX, srcY, srcW, srcH, SRCINVERT

; now clean up our memory DC

invoke SelectObject, hMemDC, hOld
invoke Deleteobject, hMemDC
invoke DeleteObject, hMask
ret

transBlt ENDP
:alright:
Posted on 2002-03-01 13:06:16 by The Worrier King