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.
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: