;================================================================================================

.const
	ROLLUP_FIXED					EQU				000000000000000000000000000000001b

.data
	szRollUpClass					db				"epcRollUp",0

.data?

.code

;================================================================================================

InitRollup	PROC
	LOCAL RollUpClass:WNDCLASSEX
	
	mov RollUpClass.cbSize, SIZEOF WNDCLASSEX
	INVOKE GetClassInfoEx, NULL, 32770,  ADDR RollUpClass
	
	mov RollUpClass.lpszClassName, OFFSET szRollUpClass
	m2m RollUpClass.lpfnWndProc, OFFSET RollupWindowProc
	invoke RegisterClassEx, ADDR  RollUpClass

	ret
InitRollup	ENDP

;================================================================================================

.data?
	hChild				HANDLE					?
	RollUpMoving		DWORD					?
	RollUpMoving_x		DWORD					?
	RollUpMoving_y		DWORD					?
	
.code	

RollupWindowProc	PROC	USES edi esi ebx	hWnd:HWND, uMsg:DWORD, wParam:DWORD, lParam:DWORD
	LOCAL	r					:RECT
	LOCAL	mp					:POINT 
	local	hbBlack				:DWORD
	local	p					:POINT

	.IF uMsg == WM_CREATE
		invoke SetWindowText, hWnd, addr szRollUpName
		invoke CreateDialogParam, hInstance, 102, hWnd, addr ActualDialogProc, NULL
		mov hChild, eax
		invoke GetClientRect, hChild, addr r
		add r.top, 16
		inc r.left
		invoke ShowWindow, hChild, SW_SHOW
		invoke MoveWindow, hChild, r.left, r.top, r.right, r.bottom, TRUE
		invoke GetWindowRect, hWnd, addr r
		invoke MoveWindow, hWnd, r.left, r.top, 100, 16, TRUE
	.ELSEIF uMsg == WM_CLOSE
	.ELSEIF uMsg == WM_ERASEBKGND
		
		invoke GetClientRect, hWnd, addr r
		push r.bottom
		mov r.bottom, 16
		invoke DrawEdge, wParam, addr r, BDR_RAISEDINNER , BF_MIDDLE  
		pop r.bottom
		invoke DrawEdge, wParam, addr r, BDR_RAISEDINNER , BF_RECT
		invoke GetClientRect, hWnd, addr r
		inc r.top
		add r.left, 16
		sub r.right, 2
		mov r.bottom, 14
		invoke DrawCaption, hWnd, wParam, addr r, DC_SMALLCAP + DC_TEXT + DC_ACTIVE + DC_GRADIENT
		inc r.top
		dec r.bottom
		sub r.left, 14
		inc r.left
		mov eax, r.bottom
		sub eax, r.top
		m2m r.right, r.left
		add r.right, eax
		invoke GetWindowLong, hWnd, GWL_USERDATA
		and eax, ROLLUP_FIXED
		.IF eax
			invoke DrawFrameControl, wParam, addr r, DFC_CAPTION, DFCS_CAPTIONMIN
		.ELSE
			invoke DrawFrameControl, wParam, addr r, DFC_CAPTION, DFCS_CAPTIONMAX
		.ENDIF	

		xor eax, eax
		ret
	.ELSEIF uMsg == WM_TIMER
		invoke GetCapture
		.IF ! eax
			invoke KillTimer, hWnd, 1
			invoke SetCapture, hWnd
			invoke SendMessage, hWnd, WM_MOUSEMOVE, NULL, NULL
		.ENDIF	
	.ELSEIF uMsg == WM_LBUTTONDOWN
		invoke GetWindowRect, hWnd, addr r
		invoke GetCursorPos, addr mp
		mov eax, mp.x 
		mov ebx, mp.y
		add r.top, 16
		.IF r.top > 80000000h
			mov r.top, 0
		.ENDIF
		add r.left, 16
		.IF ( ebx < r.top )
			.IF ( eax > r.left ) || ( r.left > 80000000h)
				mov RollUpMoving_x, eax
				mov RollUpMoving_y, ebx
				mov RollUpMoving, TRUE
				invoke SetCapture	,hWnd
				mov eax, TRUE
				ret
			.ELSE
				invoke GetWindowLong, hWnd, GWL_USERDATA
				xor eax, ROLLUP_FIXED
				invoke SetWindowLong, hWnd, GWL_USERDATA, eax
				invoke GetClientRect, hWnd, addr r
				invoke InvalidateRect, hWnd, addr r, TRUE
			.ENDIF
		.ELSE
			invoke ReleaseCapture
			invoke DefWindowProc, hWnd, uMsg, wParam, lParam
			push eax
			invoke SetTimer, hWnd, 1, 100, NULL
			pop eax
			ret							
		.ENDIF
	.ELSEIF uMsg == WM_LBUTTONUP
		.IF RollUpMoving 
			invoke ReleaseCapture	
			mov RollUpMoving, FALSE
		.ENDIF	
	.ELSEIF uMsg == WM_MOUSEMOVE
		.IF RollUpMoving
			mov eax, wParam
			and eax, MK_LBUTTON
			.IF ! eax
				mov RollUpMoving, FALSE
				mov eax, TRUE
				ret
			.ENDIF 
			invoke GetWindowRect, hWnd, addr r
			mov eax, r.top
			sub r.bottom, eax
			mov eax, r.left
			sub r.right, eax
			invoke GetCursorPos, addr mp
			mov eax, mp.x
			mov ebx, mp.y
			sub eax, RollUpMoving_x
			sub ebx, RollUpMoving_y
			add r.left, eax
			add r.top, ebx
			m2m RollUpMoving_x, mp.x
			m2m RollUpMoving_y, mp.y
			invoke MoveWindow, hWnd, r.left, r.top, r.right, r.bottom, TRUE
			ret
		.ENDIF
		invoke GetCapture
		.IF eax != hWnd
			invoke SetCapture, hWnd
			invoke GetWindowRect, hWnd, addr r
			push r.left
			push r.top
			invoke GetClientRect, hChild, addr r
			pop r.top
			pop r.left
			add r.right, 2
			add r.bottom, 17
			invoke GetFocus
			.IF eax != hChild 
				invoke SetFocus, hChild
			.ENDIF	
			invoke MoveWindow, hWnd, r.left, r.top, r.right, r.bottom, TRUE
			invoke GetClientRect, hWnd, addr r
			invoke InvalidateRect, hWnd, addr r, TRUE
			mov eax, TRUE
			ret
		.ENDIF
		invoke GetWindowRect, hWnd, addr r
		invoke GetCursorPos, addr mp
		mov eax, mp.x 
		mov ebx, mp.y
		.IF r.left > 80000000h
			mov r.left, 0
		.ENDIF
		.IF r.top > 80000000h
			mov r.top, 0
		.ENDIF
		.IF ( eax < r.left ) || ( eax >= r.right ) || (ebx < r.top) || (ebx >= r.bottom)
			invoke GetWindowRect, hWnd, addr r
			invoke GetWindowLong, hWnd, GWL_USERDATA
			and eax, ROLLUP_FIXED
			.IF ! eax 			
				invoke MoveWindow, hWnd, r.left, r.top, 100, 16, TRUE
			.ENDIF	
			invoke GetClientRect, hWnd, addr r
			invoke InvalidateRect, hWnd, addr r, TRUE
			invoke SetFocus, hMainDialog
			invoke ReleaseCapture
			mov eax, TRUE
			ret
		.ENDIF
		add r.top, 16
		.IF ( ebx > r.top ) && (eax > r.left) && (eax < r.right) && (ebx < r.bottom)
			invoke ReleaseCapture
			invoke DefWindowProc, hWnd, uMsg, wParam, lParam
			push eax
			invoke SetTimer, hWnd, 1, 100, NULL
			pop eax
			ret							
		.ENDIF
	.ELSE
		invoke DefWindowProc, hWnd, uMsg, wParam, lParam
		ret
	.ENDIF
	mov eax, TRUE
	ret
RollupWindowProc	ENDP

RollupHandler		PROC	USES edi esi ebx	hWnd:HWND, uMsg:DWORD, wParam:DWORD, lParam:DWORD
	ret
RollupHandler		ENDP