;Win01.asm : Keyboard Input - WNDPROC Parsing (April 27, 2024)
;===================================================================
;Win01.ASM : Keyboard Input
;   This app adds basic key trapping to WndProc. The only function
;   of the key trap will be to exit the program on ESC key.
;	It also introduces some code for parsing Windows messages. 
;====================================================================
;   The " %include " paths at the start of the file might need to be
;       changed to suit your own disk directory setup.
;   Command Lines:
;       Assembly: nasm -f win32 win01.asm -o win01.obj;
;       Link:;
;       GoLink.exe: golink.exe /entry:start win01.obj kernel32.dll user32.dll
                                                                                    ;
%include '\nasm32\inc\win32\windows.inc'
%include '\nasm32\inc\win32\kernel32.inc'
%include '\nasm32\inc\win32\user32.inc'
%include '\nasm32\inc\nasm32.inc'

;                           ------------
;                               DATA
;                           ------------

[section .data]

;-------
;HANDLES
;-------
hInstance dd 0
hWnd dd 0

;---------------
;VARIOUS LABELS
;---------------
szTitle db 'Win01 : A Simple Window With Keyboard Input : ESC Or Close Button To Exit',0x0
szClass db 'win01 Class',0x0

;-------
;STRUCS	  
;-------
wcx  times WNDCLASSEX_size dd 0	;Declare a memory block of WNDCLASSEX size.
msg times MSG_size dd 0			;Declare a memory block of MSG size.

;                           ------------
;                             CODE
;                           ------------


[section .text]

start:		;This is for GoLink

	proc Win01
          invoke GetModuleHandleA, dword NULL
          mov [hInstance], eax
          invoke WinMain,dword [hInstance],NULL,NULL,dword SW_SHOWNORMAL
          invoke ExitProcess,dword NULL
ret
    endproc ;Win01

;-=====================  Main Procedure  ===============================

	proc WinMain ,hInst,hPinst,CmdLn,dwShow

;Memory block reserved for wcx [WNDCLASSEX] has no data yet. 

push dword WNDCLASSEX_size
pop dword [wcx  + WNDCLASSEX.cbSize]

push dword argv(hInst)      
pop dword [wcx  + WNDCLASSEX.hInstance]

push dword szClass
pop dword [wcx  + WNDCLASSEX.lpszClassName]

push dword WndProc    ; Adr of WndProc
pop dword [wcx  + WNDCLASSEX.lpfnWndProc]

push dword COLOR_BTNFACE +1
pop dword [wcx  + WNDCLASSEX.hbrBackground]

        invoke RegisterClassExA, dword wcx 

;---------------
;Load Window
;---------------
        invoke CreateWindowExA,\
          WS_EX_OVERLAPPEDWINDOW,\
                         szClass,\
                         szTitle,\
         WS_OVERLAPPEDWINDOW +WS_VISIBLE ,\
                   50, 50, 600, 200,\
                               NULL,\
                               NULL,\
        [wcx  + WNDCLASSEX.hInstance],\
                               NULL

        mov [hWnd], eax
	
;-------------------------
;Process Windows Messages
;-------------------------
       MsgGet:
       invoke GetMessageA, dword msg, dword NULL, dword NULL, dword NULL
		cmp eax,0
			jnz MsgProcess
		jmp MsgEnd
   
       MsgProcess:
		invoke TranslateMessage, dword msg
		invoke DispatchMessageA, dword msg
		jmp MsgGet

       MsgEnd:
		mov eax,[msg +MSG.wParam]
ret 
	endproc ;WinMain

;=========================  WindProc ====================================

	proc WndProc, hWin, uMsg, wParam, lParam

	IsKeyPress?:
		cmp dword argv(uMsg),dword WM_CHAR
		  jnz IsDestroy?	;Not a key press. Check for WM_DESTROY

;----------------
;WM_CHAR detected
;----------------
		mov eax,dword argv(wParam)
		cmp eax, 01bh   ; ESC Key ?
		   jz IsEsc
		xor eax,eax
ret	        			;Not the  wParam we wanted but we handled it
						; so don't pass it to DefWndProc.

;--------------
;Escape key hit
;--------------
			IsEsc:                                    	
			invoke SendMessageA,dword argv(hWin),WM_CLOSE,NULL,NULL 
			xor eax,eax	
ret						;WM_CHAR msg handled so DON'T pass it back to WndProc

	IsDestroy?:
		cmp dword argv(uMsg),dword WM_DESTROY
		    jnz DefWndProc	; No message of interest to us. Pass to default
            				;  processor DefWindowProc.

;------------------
;WM_DESTROY message
;------------------
	Exit:					
		invoke PostQuitMessage, NULL
ret

;-------------------------
;Default Message Processor
;-------------------------
	DefWndProc:
		invoke DefWindowProcA, dword argv(hWin), dword argv(uMsg),\
                               dword argv(wParam), dword argv(lParam)
ret
	endproc     ;WndProc

;mcamember May 9, 2024