.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
include \masm32\include\masm32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\m32lib\masm32.lib

WinMain proto :DWORD,:DWORD,:DWORD,:DWORD
IDB_MAIN   equ 1

.data
ClassName db "SimpleWin32ASMBitmapClass",0
AppName  db "Win32ASM Simple Bitmap Example",0
LibName db "Skin.dll",0
FunctionName db "MakeRegion",0
done DWORD FALSE
lpOut DB 1024 dup(0)
szMsg DB "ERROR NUMBER %lu HAS OCCURRED!",0
Message DB 100 dup(0)

.data?
hInstance HINSTANCE ?
CommandLine LPSTR ?
hBitmap dd ?
MakeRegion DWORD ?
hLib DWORD ?

.code
start:
	invoke GetModuleHandle, NULL
	mov    hInstance,eax
	invoke GetCommandLine
	mov    CommandLine,eax
	invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
	invoke ExitProcess,eax

WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
	LOCAL wc:WNDCLASSEX
	LOCAL msg:MSG
	LOCAL hwnd:HWND
	mov   wc.cbSize,SIZEOF WNDCLASSEX
	mov   wc.style, CS_HREDRAW or CS_VREDRAW or CS_DBLCLKS
	mov   wc.lpfnWndProc, OFFSET WndProc
	mov   wc.cbClsExtra,NULL
	mov   wc.cbWndExtra,NULL
	push  hInstance
	pop   wc.hInstance
	mov   wc.hbrBackground,COLOR_WINDOW+1
	mov   wc.lpszMenuName,NULL
	mov   wc.lpszClassName,OFFSET ClassName
	invoke LoadIcon,NULL,IDI_APPLICATION
	mov   wc.hIcon,eax
	mov   wc.hIconSm,eax
	invoke LoadCursor,NULL,IDC_ARROW
	mov   wc.hCursor,eax
	invoke RegisterClassEx, addr wc
	INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\
           WS_POPUP,CW_USEDEFAULT,\
           CW_USEDEFAULT,284,277,NULL,NULL,\
           hInst,NULL
	mov   hwnd,eax
	invoke ShowWindow, hwnd,SW_SHOWNORMAL
	invoke UpdateWindow, hwnd
	.while TRUE
		invoke GetMessage, ADDR msg,NULL,0,0
		.break .if (!eax)
		invoke TranslateMessage, ADDR msg
		invoke DispatchMessage, ADDR msg
	.endw
	mov     eax,msg.wParam
	ret
WinMain endp

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
   LOCAL ps:PAINTSTRUCT
   LOCAL hdc:HDC
   LOCAL hMemDC:HDC
   LOCAL rect:RECT
   LOCAL myDC:HDC
   LOCAL point:RECT

   .if uMsg==WM_CREATE
	invoke LoadBitmap,hInstance,IDB_MAIN
	mov hBitmap,eax
	invoke GetWindowDC,hWnd
	mov hdc,eax
	invoke CreateCompatibleDC,hdc
	mov hMemDC,eax
      	invoke SelectObject,hMemDC,hBitmap
      	invoke GetWindowRect,hWnd,addr rect
	
;Skin code
;Regions are nothing but the part of a window that is visible, they start at points 0,0 (top left points of the window, not the client area)
;So to make a window to have a certain form, you just need to make a region with that specific form
;The MakeRegion function returns a region consisting of the bitmap you give it

		invoke LoadLibrary,addr LibName 
		mov hLib,eax 
	     	invoke GetProcAddress,hLib,addr FunctionName 
		mov MakeRegion,eax
		invoke GetClientRect,hWnd,ADDR rect
		mov eax,hMemDC
		mov myDC,eax
		push rect.bottom
		push rect.right
		push hMemDC 
		call [MakeRegion]

;Regions have to be set to the window you wish to apply them to via: SetWindowRgn
;you can do this whenever you wish to
;using a value of 0 (zero) resets the region e.g. invoke SetWindowRgn,hWnd,0,TRUE

		invoke SetWindowRgn,hWnd,eax,TRUE

;end skin code
	
			
	invoke ReleaseDC,hWnd,hdc
	invoke DeleteDC,hMemDC
    .elseif uMsg==WM_LBUTTONDBLCLK
    	invoke DestroyWindow,hWnd
    .elseif uMsg==WM_PAINT
    	invoke GetClientRect,hWnd,addr rect
	invoke BeginPaint,hWnd,addr ps
	mov hdc,eax
          	invoke CreateCompatibleDC,hdc
	mov hMemDC,eax
	invoke SelectObject,hMemDC,hBitmap
	invoke BitBlt,hdc,0,0,rect.right,rect.bottom,hMemDC,0,0,SRCCOPY
	invoke DeleteDC,hMemDC
	invoke EndPaint,hWnd,addr ps	
    .elseif uMsg==WM_DESTROY
    	invoke DeleteObject,hBitmap
	invoke PostQuitMessage,NULL
    .ELSEIF uMsg==WM_LBUTTONDOWN
	call ReleaseCapture
	invoke SendMessage,hWnd,WM_NCLBUTTONDOWN, HTCAPTION,0
    .ELSE
	invoke DefWindowProc,hWnd,uMsg,wParam,lParam		
	ret
    .ENDIF
     xor eax,eax
     ret
WndProc endp
end start
