.386 
.model flat,stdcall 
option casemap:none 
include \masm32\include\windows.inc 
include \masm32\include\user32.inc 
include \masm32\include\kernel32.inc 
include \masm32\include\gdi32.inc

includelib \masm32\lib\user32.lib 
includelib \masm32\lib\kernel32.lib 
includelib \masm32\lib\gdi32.lib


.const
TRUE equ 1
FALSE equ 0
.data 
Message DB 10 dup(0)
.code 
DllEntry proc hInstDLL:HINSTANCE, reason:DWORD, reserved1:DWORD 
        mov  eax,TRUE 
        ret 
DllEntry Endp 

MakeRegion PROC var_hDC:HDC,var_PicWidth:DWORD,var_PicHeight:DWORD
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; MakeRegion returns a region that can be applied to (any) window of which you have the handle based on a bitmap you provide it with ;
; This bitmap needs to be passed to the routine in the form of a DC, also the width and height of the picture need to be specified   ;
; After this call the caller still needs to invoke SetWindowRgn to a window with this returned region itself, this routine only      ;
; returns the region so that this region itself can be used in further operations where needed.                                      ;
; The routine itself creates the final region by scanning the picture for lines of 1 pixel high to show, create a region from it and ;
; combining them to 1 final region                                                                                                   ;
; e.g. (T: transparant, N: non-transparant)                                                                                          ;
;	 suppose this is the first row of your image: TTTNNNNNNNTTTNN                                                                  ;
;	 This row will be translated into 2 regions: 1 region from col-positions 3 to 10                                               ;
;						     		   1 region from col-position 13 to the end of the row                               ; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



LOCAL var_X:DWORD				; Col value
LOCAL var_Y:DWORD				; Row value
LOCAL var_StartLineX:DWORD		; start location of a region
LOCAL var_FullRegion:DWORD		; Combination of all Regions found so far
LOCAL var_LineRegion:DWORD		; Current region
LOCAL var_TransparantColor:DWORD	; color that is used to indicate transparancy
LOCAL var_InFirstRegion:DWORD		; First Region state 
LOCAL var_Inline:DWORD			; Inline Region state

mov var_InFirstRegion,TRUE
mov var_Inline,FALSE
mov var_X,0
mov var_Y,0
mov var_StartLineX,0


invoke GetPixel,var_hDC,0,0 ; Get the upper left pixel of the image to determine the color that the user intended to be transparant
mov var_TransparantColor,eax

mov ebx, var_PicHeight
	.WHILE var_Y < ebx ; Loop through all rows of the picture
		mov ebx, var_PicWidth
	
		.WHILE var_X <= ebx ; Loop through the columns of each row

			invoke GetPixel,var_hDC,var_X,var_Y ; Get the pixel at current location
			mov ebx, var_PicWidth
			
			; Check if the pixel==transparantcolor or if the routine has reached the end of the row
			.IF eax==var_TransparantColor || var_X==ebx 

				; it did, now check wether we are creating a region or wether this is just another transparant pixel
				; if it's another transparant pixel then just go to the next pixel, else create a region between the startpixel
				; and the current found transparant or endrow pixel
				
				.IF var_Inline==TRUE 
					mov var_Inline,FALSE
					mov ebx,var_Y
					inc ebx
					invoke CreateRectRgn,var_StartLineX,var_Y,var_X,ebx
					mov var_LineRegion,eax
					.IF var_InFirstRegion==TRUE 
						; if the region created is the first region created 
						; then we don't have anything to combine it with yet

						push var_LineRegion
						pop var_FullRegion
						mov var_InFirstRegion,FALSE
					.ELSE
						; Combine the newly created region with the previously created regions 
						; and store the final result in the Full_Region variable

						invoke CombineRgn,var_FullRegion,var_FullRegion,var_LineRegion,RGN_OR
						invoke DeleteObject,var_LineRegion ; always clean up afterwards
					.ENDIF
				.ENDIF
			.ELSE
				; the pixel is neither transparant nor the end of the row nor are we currently in the creation of a line region
				; so this pixel is the first pixel of a new line region to create
				
				.IF var_Inline==FALSE
					mov var_Inline,TRUE ; make sure that the inline state is set to true 
					push var_X
					pop var_StartLineX ; set the startpixel to the current pixellocation
				.ENDIF
			.ENDIF
			inc var_X ; increase the col location
			mov ebx, var_PicWidth
		.ENDW
		inc var_Y ;increase the rowlocation
		mov var_X,0 ;reset the col location
		mov ebx, var_PicHeight
	.ENDW


mov eax, var_FullRegion ; return the final created region to the caller

ret

MakeRegion ENDP
    
End DllEntry 
