;Win05.ASM : LoadCursor / GetDC / TextOutA / ReleaseDC (May 9, 2024)
;===================================================================
;NOTES:
;   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 win05.asm -o win05.obj
;       GoLink.exe: golink.exe /entry:start win05.obj  kernel32.dll user32.dll gdi32.dll

%include '\nasm32\inc\win32\windows.inc'
%include '\nasm32\inc\win32\kernel32.inc'
%include '\nasm32\inc\win32\user32.inc'
%include '\nasm32\inc\nasm32.inc'
%include '\nasm32\inc\win32\gdi32.inc'	; GDI32 is needed for GetDC

;                          ---------------
                           [section .data]
;                          ---------------
;-------
;STRUCS 
;-------

wcx times WNDCLASSEX_size db 0
msg times MSG_size db 0
ps times PAINTSTRUCT_size db 0
paintRect times RECT_size db 0

;-------
;Messages
;-------
 
MsgBegPaint db  " This message brought to you by BeginPaint/TextOut/EndPaint "
lMsgBegPaint equ $-MsgBegPaint	;len MsgBegPaint
MsgPressG db " Press 'g' for GetDc message"          
lMsgPressG equ $-MsgPressG	;len MsgPressG

MsgGetDC db "This message brought to you by GetDC / TextOutA / ReleaseDC",0
lMsgGetDC equ $-MsgGetDC-1
MsgPressSpace db " Press 'Space' to clear the GetDC Line"          
lMsgPressSpace equ $-MsgPressSpace	;len MsgPressSpace


;-------
;Handles
;-------

hDC0 dd 0       ; Handle to the GetDC Device Context
hDC1 dd 0		; Handle to the BeginPaint Device Context
hInstance dd 0
hWnd dd 0

;----------------
;Various labels
;----------------
szTitle db 'win05 : Window Using GetDC / TextOut / ReleaseDC / LoadCursor',0x0
szClass db 'win05 Class',0x0
;                          ---------------
                           [section .text]
;                          ---------------

start:       

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

proc WinMain ,hInst,hPinst,CmdLn,dwShow

;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]

push dword CS_VREDRAW +CS_HREDRAW
pop dword [wcx + WNDCLASSEX.style]
		
      invoke LoadCursorA,NULL,IDC_UPARROW	;reports handle in eax

push dword eax
pop  dword   [wcx +  WNDCLASSEX.hCursor]	;Cursor handle into WNDCLASSEX



;Register the class
      invoke RegisterClassExA, dword wcx	
	
;Load the window
     invoke CreateWindowExA,\
     WS_EX_OVERLAPPEDWINDOW,\
                    szClass,\
                    szTitle,\
          WS_OVERLAPPEDWINDOW +WS_VISIBLE ,\
            50, 120, 600, 232,\
                          NULL,\
                          NULL,\
     [wcx + WNDCLASSEX.hInstance],\
                          NULL
     mov [hWnd], eax
;--------------
; message pump
;--------------
      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:
         ret
      endproc ;WinMain

;============================= WndProc =====================================

      proc WndProc, hWin, uMsg, wParam, lParam

        cmp dword argv(uMsg),dword WM_CHAR	;WM_CHAR for "alphabet chars"
        	jz wpChar
        cmp dword argv(uMsg),dword WM_KEYDOWN ;WM_KEYDOWN for "non-alphabet chars"
          jz near  wpKey
        cmp dword argv(uMsg),WM_PAINT
        	jnz IsDestroy?

;WM_PAINT
wpDoPaint:		
		invoke Painter, dword argv(hWin)
ret
IsDestroy?:
        cmp dword argv(uMsg),WM_DESTROY
          jz near  wpExit
        jmp DefWndProc

;------------------- WM_CHAR / GetDC  ----------------------------------------
        wpChar:
		cmp dword argv(wParam),20h	;Space bar pressed ?
			jnz wpChar1

;Space bar pressed.
;Load paintRect with display coods of "This message . . . GetDC"
;										". . . Space to clear. . ."
;These values were determined by experiment.
		mov dword [paintRect +RECT.left],0
        mov dword [paintRect +RECT.top],55
        mov dword [paintRect +RECT.right],420
        mov dword [paintRect +RECT.bottom],87

;Invalidate the "GetDC" display text area.
		invoke InvalidateRect,dword argv(hWin),paintRect,1
		jmp ExitwpChar

		wpChar1:
		cmp dword argv(wParam),'g'
           	jnz ExitwpChar           
;"g" key pressed.
		invoke PaintDC, dword argv(hWin)			
		ExitwpChar:
           xor eax,eax
ret

        wpKey:
      	    cmp dword argv(wParam), VK_ESCAPE  ; ESC Key ?
          	    jz near  wpIsEscKey       ; If ESC then kill the window . . .
            mov eax,0    			; . . . otherwise return.
		ret
        wpIsEscKey:
              invoke SendMessageA,dword argv(hWin),WM_CLOSE,NULL,NULL
      		xor eax,eax
        ret

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

;Exit Procecure
		wpExit:
          invoke PostQuitMessage,dword NULL
          xor eax,eax
      ret

;----------------------------- Procedures -----------------------------
	proc Painter, painthWin
			invoke BeginPaint, dword argv(painthWin), ps
            mov dword [hDC1],eax

			invoke TextOutA,dword [hDC1],10,10,MsgBegPaint,lMsgBegPaint
			invoke TextOutA,dword [hDC1],10,35,MsgPressG,lMsgPressG

			invoke EndPaint, dword argv(painthWin), ps
		xor eax,eax
ret 4	;Painter called with one arg.
	endproc ;Painter

;----------------------
;Paint with GetDC
	proc	PaintDC, getdchWin
			invoke GetDC,dword argv (getdchWin)
			mov dword [hDC0],eax

			invoke TextOutA,dword [hDC0],10,55,MsgGetDC,lMsgGetDC
			invoke TextOutA,dword [hDC1],10,71,MsgPressSpace,lMsgPressSpace


           invoke ReleaseDC, dword argv (getdchWin), dword [hDC0]
			xor eax,eax
	ret 4 ;PaintDc called with one arg.
	endproc	;PaintDC
;==============================================
;The following link contains extensive information on painting. 

;https://msdn.microsoft.com/en-us/library/dd183315.aspx

;mcamember May 9, 2024