;WIN00.ASM : a simple Windows template for NASM 


;WIN00.ASM : A simple Windows template for NASM (last mod. April 25, 2024)

;   The " %include " paths at the start of the file might need to be
;       changed to suit your own disk directory setup.
;
;	Assembly: nasm -f win32 win00.asm -o win00.obj;
;	Link: GoLink.exe: golink.exe /entry:start win00.obj kernel32.dll user32.dll

;========================= INCLUDE FILES =====================================

%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

ModName db "Win00.exe",0
szTitle db 'Win00 : A Simple NASM Window : Click The Close Button To Exit -------->',0x0
szClass db 'win00 Class',0x0

;Define wcx which is our own instance of WNDCLASSEX struc
;See note at end concerning STRUC definitions.

    wcx:
    istruc WNDCLASSEX
        at WNDCLASSEX.cbSize,       dd WNDCLASSEX_size
        at WNDCLASSEX.style,        dd CS_VREDRAW + CS_HREDRAW
        at WNDCLASSEX.lpfnWndProc,  dd WndProc
        at WNDCLASSEX.cbClsExtra,   dd NULL
        at WNDCLASSEX.cbWndExtra,   dd NULL
        at WNDCLASSEX.hInstance,    dd NULL
        at WNDCLASSEX.hIcon,        dd NULL
        at WNDCLASSEX.hCursor,      dd NULL
        at WNDCLASSEX.hbrBackground,dd COLOR_BTNFACE + 1
        at WNDCLASSEX.lpszMenuName, dd NULL
        at WNDCLASSEX.lpszClassName,dd szClass
        at WNDCLASSEX.hIconSm,      dd NULL
    iend

;Define our own instance of MSG struc

    msg:
    istruc MSG
        at MSG.hwnd,               dd    NULL
        at MSG.message,            dd    NULL
        at MSG.wParam,             dd    NULL
        at MSG.lParam,             dd    NULL
        at MSG.time,               dd    NULL
        at MSG.pt,                 dd    NULL
    iend

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

[section .text]

start:         ;Start offset for GoLink.exe
	
	proc win00
    	invoke GetModuleHandleA, dword NULL
		mov [hInstance], eax
		invoke WinMain,dword [hInstance],NULL,NULL,SW_SHOWNORMAL
		invoke ExitProcess,eax
ret
	endproc ;win00
	
	proc WinMain ,hInst,hPinst,CmdLn,dwShow
		mov eax, dword argv(hInst)      
		mov      [wcx + WNDCLASSEX.hInstance], eax

		invoke RegisterClassExA, dword wcx

;---------------
;Create the Window
;---------------

		invoke CreateWindowExA,\
			WS_EX_OVERLAPPEDWINDOW,\
			               szClass,\
			               szTitle,\
			 WS_OVERLAPPEDWINDOW +WS_VISIBLE ,\
			         50, 50, 640, 200,\
				           NULL,\
				            NULL,\
				   dword argv(hInst),\
				               NULL

;EAX returns handle to window. Store it
		mov [hWnd], eax

;------------------------
;Process Windows Messages
;------------------------
		MsgGet:
		invoke GetMessageA, msg, NULL, NULL, NULL
		cmp eax,0
			jnz MsgProcess
		jmp MsgEnd

		MsgProcess:
		invoke TranslateMessage, msg
		invoke DispatchMessageA, msg
		jmp MsgGet
		
        MsgEnd:
		mov eax,dword [msg +MSG.wParam]
ret
	endproc ;WinMain
;=================================================================
;----------------
;WNDPROC Callback
;----------------	
	proc WndProc, hWin, uMsg, wParam, lParam

		IsDestroy?:
		cmp dword argv(uMsg),dword WM_DESTROY
			jnz DefWndProc  ;Msg not handled. Pass it to DefWndProc
		jmp ExitWin00

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

		ExitWin00:
		invoke PostQuitMessage,dword NULL   ;See Win00.rtf
		xor eax,eax
ret

	endproc     ;WndProc
;-------------------------------------------------
;Note on the declaration of STRUCs : 
;	In this first template ( Win00 ) STRUCs are declared in the method
;	shown in Nasm_Man.chm  which involves copying the entire STRUC from
;	Windows.inc into our own data area and assigning a variable name
;	( wcx ) to create an instance of the  WNDCLASSEX STRUC using the istruc / iend
;	construct.
;	Values which won't change can be assigned here. Values which can't be
;	assigned until run time are filled with NULL for now. 
; 
;    wcx:
;    istruc WNDCLASSEX
;        at WNDCLASSEX.cbSize,       dd WNDCLASSEX_size
;        at WNDCLASSEX.style,        dd CS_VREDRAW + CS_HREDRAW
;        at WNDCLASSEX.lpfnWndProc,  dd WndProc
;        at WNDCLASSEX.cbClsExtra,   dd NULL
;        at WNDCLASSEX.cbWndExtra,   dd NULL
;        at WNDCLASSEX.hInstance,    dd NULL
;        at WNDCLASSEX.hIcon,        dd NULL
;        at WNDCLASSEX.hCursor,      dd NULL
;        at WNDCLASSEX.hbrBackground,dd COLOR_BTNFACE + 1
;        at WNDCLASSEX.lpszMenuName, dd NULL
;        at WNDCLASSEX.lpszClassName,dd szClass
;        at WNDCLASSEX.hIconSm,      dd NULL
;    iend


;
;		Then we use the Code section to fill in those values which won't 
;		be available until run time.
; 
;			proc WinMain ,hInst,hPinst,CmdLn,dwShow 
;			mov eax, dword argv(hInst)       
;			mov [wcx +WNDCLASSEX.hInstance], eax . . .
;              etc.
; 
;      There is a simpler way to do this which we'll see in Win00a.asm.
;
;mcamember July 14, 2023
;mcamember May 8, 2024