
; This is Win32 demo uses a modal dialog to allow data entry using a spin control
; in conjuntion with an edit box

; Ron Thomas 4/9/99 

.386
.model flat, stdcall

include windows.inc

include user32.inc
include kernel32.inc
include gdi32.inc
include comctl32.inc

includelib user32.lib
includelib kernel32.lib
includelib gdi32.lib
includelib comctl32.lib				; We use common controls

WinMain	  PROTO :DWORD, :DWORD, :DWORD, :SDWORD

;lstrlenA	PROTO	WINAPI	:LPCSTR		; Not included in latest l2inc output
;lstrlen	textequ	<lstrlenA>		; but lib can't be missing as function works 

.data

ClassName     db "SimpleWinClass",0
AppName       db "Control Menu",0
MenuName      db "ControlMenu",0
SpinDlgName   db "SpinDlgBox",0		; Name of Dialog "Spin" integer entry box 
AboutDlgName  db "About",0		; Name of About dialog box	
;screentext    db "Variable circle size",0; Message about application
default       dd  150			; Initialised value value for Spin control 
	
.data?

hInstance HINSTANCE ?
CommandLine LPSTR   ?
hPen	dd	    ?
iradius dd	    ?

.const

spinmin		equ 100 		; Min value for spin control
spinmax		equ 200			; Max value for spin control

range		equ spinmin SHL 16 or spinmax	; Spin range; high word is min & low word is max 

ID_OK	        equ 1
ID_CANCEL       equ 2
ID_CONTROLS_INT equ 40002
ID_HELP_ABOUT   equ 40003
ID_HELP_EXIT    equ 40004

IDC_INTEGER equ 1000
IDC_SPIN1   equ 1001 	
IDC_EDIT    equ 3000
IDC_BUTTON  equ 3001
IDC_EXIT    equ 3002

;Macros
;------
RGB	MACRO   red, green, blue	;; Get composite number from red green and blue bytes 

	mov	al,blue			;; ,,,blue	
	shl	eax,8			;; ,,blue,

	add	al,green		;; ,,blue,green
	shl	eax,8			;; ,blue,green,
	add	al,red			;; ,blue,green,red
	and	eax,0FFFFFFh		;; Mask out top byte to complete COLORREF dword 

	ENDM

LOWORD	MACRO 	bigword	;; Retrieves the low word from double word argument

	mov	eax,bigword
	and	eax,0FFFFh	;; Set to low word 
	ENDM
;---------------------------------------------------------------------------
.code
start:
	invoke GetModuleHandle, NULL
	mov    hInstance,eax
	invoke GetCommandLine
        invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
	invoke ExitProcess,eax
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:SDWORD
	LOCAL wc:WNDCLASSEX
	LOCAL msg:MSG
        LOCAL hwnd:HWND
	mov   wc.cbSize,SIZEOF WNDCLASSEX
	mov   wc.style, CS_HREDRAW or CS_VREDRAW
	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,OFFSET MenuName
	mov   wc.lpszClassName,OFFSET ClassName
        invoke LoadIcon,NULL,IDI_APPLICATION
	mov   wc.hIcon,eax
        mov   wc.hIconSm,0
        invoke LoadCursor,NULL,IDC_ARROW
	mov   wc.hCursor,eax
        invoke RegisterClassEx, addr wc
        INVOKE CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,ADDR AppName,\
           WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
           CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,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

SpinDlgProc PROC hDlg:HWND,iMsg:DWORD,wParam:WPARAM, lParam:LPARAM

LOCAL icex:INITCOMMONCONTROLSEX 

	mov	icex.dwSize,sizeof icex

	mov	icex.dwICC,ICC_UPDOWN_CLASS

	invoke  InitCommonControlsEx, ADDR icex		; Initialise use of controls
 
        mov  eax,iMsg

        .IF     eax==WM_INITDIALOG

;	We now intialise the spin control for edit control (identified as an autobuddy)
 
	    invoke SendDlgItemMessage, hDlg, IDC_SPIN1, UDM_SETRANGE,0,range ; Set range 
 	    invoke SendDlgItemMessage, hDlg, IDC_SPIN1, UDM_SETPOS,0,default ; Set default value
	   
        .ELSEIF eax==WM_COMMAND

	    LOWORD wParam

            .IF eax==ID_OK

                invoke GetDlgItemInt, hDlg,IDC_INTEGER, NULL, 0 ; Get data value from edit box

	        mov	default,eax	; Update the display value

		.IF	eax < spinmin

		  mov   eax,spinmin	; If entered edit box value is < min, limit it to minimum 
 		  mov   iradius,eax	; and we need to limit it to the min

	   	.ELSEIF eax > spinmax

		  mov	eax,spinmax	; Likewise limit edit box max value
		  mov   iradius,eax

		.ELSE  
		  mov	iradius,eax		; Store the required radius
		.ENDIF

		invoke EndDialog, hDlg,TRUE

	    .ELSEIF eax==IDCANCEL

		invoke EndDialog, hDlg,FALSE

            .ENDIF

        .ELSE
                mov eax,FALSE
                ret
        .ENDIF

        mov  eax,TRUE
        ret
SpinDlgProc endp

AboutDlg PROC hDlg:HWND, iMsg:DWORD, wParam:WPARAM, lParam:LPARAM

        mov  eax,iMsg

        .IF eax==WM_INITDIALOG

	  mov eax,TRUE
	  ret

        .ELSEIF eax==WM_COMMAND

            LOWORD  wParam

            .IF eax==ID_OK
                invoke EndDialog, hDlg,0	 
		mov eax,TRUE
		ret
	    .ENDIF
	    
        .ENDIF

        mov  eax,FALSE
        ret

AboutDlg endp

WndProc proc uses ebx, hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

LOCAL ps:PAINTSTRUCT, hdc:HDC, hMenu:HMENU

	mov   eax,uMsg
	
        .IF eax==WM_COMMAND

	    LOWORD wParam

	    .IF eax==ID_CONTROLS_INT	; Display the Spin dialog box

		invoke DialogBoxParam,hInstance, ADDR SpinDlgName,hWnd,ADDR SpinDlgProc,NULL 	
		invoke InvalidateRect, hWnd,NULL,TRUE
		invoke UpdateWindow, hWnd
           
            .ELSEIF eax==ID_HELP_ABOUT
                invoke DialogBoxParam,hInstance, ADDR AboutDlgName,hWnd,ADDR  AboutDlg,NULL

 	    .ELSEIF eax==ID_HELP_EXIT
	        invoke SendMessage,hWnd,WM_CLOSE,0,0
            .ENDIF
	
	.ELSEIF eax==WM_PAINT

		invoke BeginPaint,hWnd,ADDR ps
		mov    hdc,eax	

		RGB    0,0,255			; Create blue pen 	
		invoke CreatePen,PS_SOLID,8,eax ; Solid and 8 pixels wide
		mov    hPen,eax
		invoke SelectObject,hdc,hPen

;	Draw the defined circle
;	-----------------------
		mov	eax,320			; Set parameters for ellipse function
		sub	eax,iradius
		mov	ebx,240
		sub	ebx,iradius
		mov	ecx,320
		add	ecx,iradius
		mov	edx,240
		add	edx,iradius

		invoke Ellipse, hdc, eax,ebx,ecx,edx		; Draw the circle

;		invoke lstrlen, ADDR screentext			; Get string length in eax
;		invoke TextOut,hdc,100,100,ADDR screentext,eax	; Display some info
		
		invoke  ValidateRect,hWnd,NULL
		invoke  EndPaint,hWnd,ADDR ps
			  	
	.ELSEIF eax==WM_DESTROY

		invoke DeleteObject,hPen
		invoke PostQuitMessage,NULL
        .ELSE
                invoke DefWindowProc,hWnd,uMsg,wParam,lParam
                ret
	.ENDIF

        xor    eax,eax
	ret
WndProc endp

        end start
