
format PE64 GUI 5.0

include 'win64ax.inc'

	IDM_OPEN	=  96
	IDM_EXIT	= 104
	IDM_ABOUT	= 112
	IDM_SYMBOLS	= 120
	IDM_DISASM	= 128


		section '.text' code readable executable
; ============================================================================================
	entry	$

		push	rbp
		mov	rbp, rsp		; Create empty frame for WNDCLASSEX

	; Begin populating structure in reverse order

		xor	ebx, ebx		; More effective than push 0

		mov	edx, IDI_APPLICATION
		invoke	LoadIcon, rbx, rdx
		push	rax			; hIconSm

		mov	r15, rax		; hIcon needs this later on

		push	AppName 		; lpszClassName
		push	rbx			; lpszMenuName
		push	COLOR_APPWORKSPACE + 1	; hbrBackground

		mov	edx, IDC_ARROW
		invoke	LoadCursor, rbx, edx
		push	rax			; hCursor

		push	r15			; hIcon

		invoke	GetModuleHandle, rbx
		push	rax			; hInstance
		mov	[hInst], rax

		push	rbx			; cbWndExtra &  cbClsExtra
		push	MainWndProc		; lpfnWndProc

		mov	eax, CS_HREDRAW + CS_VREDRAW
		shl	rax, 32
		mov	 al, sizeof.WNDCLASSEX + 7
		push	rax			; cbSize & style

		mov	ecx, esp		; Establish pointer to WNDCLASSEX
		invoke	RegisterClassEx, rcx
		leave				; Kill structure, not required anymore

		test	ax, ax			; Did API return ATOM
		jnz	@F

	; Show operator that application initialization failed when trying to register class

		mov	edx, RegErr
	 .Err:	invoke	MessageBox, rbx, rdx, ErrTitle, MB_OK + MB_ICONSTOP
		mov	eax, 48
		jmp	.Exit

	; Create main window

	   @@:	invoke	LoadMenu, [hInst], 37
		mov	r15, rax
		invoke	CreateWindowEx, \
			WS_EX_CLIENTEDGE + WS_EX_STATICEDGE, \
			AppName, AppTitle, \
			WS_VISIBLE + WS_BORDER + WS_SYSMENU + WS_MINIMIZEBOX, \
			CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, \
			NULL, r15, [hInst] , NULL

		mov	[MWnd], rax
		or	rax, rax
		jnz	@F

	; Prompt user with error

		mov	edx, WndErr
		jmp	.Err

	; Windows message pump.

	   @@:	enter	sizeof.MSG, 0

		xor	edx, edx
		mov	 r8, rdx
		mov	 r9, rdx
		mov	rbx, rsp

	   @@:	push	rdx
		push	 r8
		push	 r9

	frame	; ---->
		invoke	GetMessage, rbx, rdx, r8, r9
		or	rax, rax		  ; Bail when NULL is passed
		jz	@F

		invoke	TranslateMessage, rbx
		invoke	DispatchMessage, rcx
	 endf	; <----

		pop	 r9
		pop	 r8
		pop	rdx
		jmp	@B

	   @@:	leave

	.Exit:	invoke	ExitProcess, rax

		align	64
; --------------------------------------------------------------------------------------------
  proc	MainWndProc	hWnd, Msg, wParam, lParam

		cmp	edx, WM_DESTROY
		jnz	@F

	; User has done something to close main window

		invoke	PostQuitMessage, 0
		xor	eax, eax
		jmp	.Exit

	    @@: cmp	edx, WM_COMMAND
		jnz	@F

		nop

		jmp	.Exit

	    @@:

		invoke	DefWindowProc, rcx, rdx, r8, r9

	 .Exit: ret
  endp

		section '.data' readable writeable
; ============================================================================================

  AppName	db	'DISASM', 0
  AppTitle	db	'Applications disassembler', 0
  RegErr	db	'Failed to register main window', 0
  WndErr	db	'Failed to create main window', 0
  ErrTitle	db	'Application Initialization', 0

		align	16

  hInst 	dq	-1
  MWnd		dq	0

		section 'rsrc' resource data readable
; ============================================================================================

  directory	RT_MENU,menus

  resource	menus, 37, LANG_ENGLISH + SUBLANG_DEFAULT, main_menu

  menu	 main_menu
		menuitem '&File', 0xA0, MFR_POPUP
		    menuitem '&Open', IDM_OPEN
		    menuitem 'E&xit', IDM_EXIT,MFR_END

		menuitem '&View', 0xB0, MFR_POPUP
		    menuitem '&Symbols', IDM_SYMBOLS
		    menuitem '&Disassembly', IDM_DISASM, MFR_END

		menuitem '&About', IDM_ABOUT, MFR_END

		section '.idata' import data readable writeable
; ============================================================================================

  library	kernel32,	'KERNEL32.DLL', \
		user32, 	'USER32.DLL'

  include 'api\kernel32.inc'
  include 'api\user32.inc'