format PE64 GUI 5.0
entry Start
include 'win64a.inc'

		section '.text' code readable executable
; ============================================================================================

	 MCmd:

	   @@: mov	ecx, [ MainWnd ]	; hWnd ( Parent Window )
	       mov	edx, NotI		; lpText
	       mov	 r8, MFunc		; lpCaption
	       mov	 r9, MB_OK + MB_ICONINFORMATION
	       invoke	 MessageBox, rcx, rdx, r8, r9
	       clc
	       ret

		align	16
;   * = * = * = * = * = * = * = * = * = * = * = * = * = * = * = * = * = * = * = * = * = * = *

	Start:	enter  sizeof.MSG, 0		; Proc frame and evenly align stack
		push   rsp
		pop    rbx
		or     rax, -1
		mov    [rbx + MSG.wParam], rax

		call	Init			; Initialize Main window
		jc	.Done			; Abort if initialization failed.

	; Begin applications message pump

	   @@:
	 frame
		xor	edx, edx
		invoke	GetMessage, ebx, edx, edx, edx
		or	eax, eax
		jz	.Done

		invoke	TranslateMessage, rbx
		invoke	DispatchMessage, rcx
		jmp	@B + 4

	.Done:	mov	rcx, [rbx + MSG.wParam]
	  endf
		jmp	[ExitProcess]

		align	8
; ============================================================================================

;       ENTRY:  RAX = Pointer to current windows map
;               RCX = hWnd
;               RDX = Msg
;                R8 = wParam
;                R9 = lParam

; --------------------------------------------------------------------------------------------

  ScanMap:	push	 r9			; lParam
		push	 r8			; wParam
		push	rdx			; Msg
		push	rcx			; hWnd

		push	rsi
		mov	rsi, rax		; Pointer to windows message map

		lodsd
		push	rbx
		mov	rbx, rax		; Pointer to windows default procedure
		lodsd
		mov	rcx, rax		; Number of messages in map

	   @@:	lodsd				; Get application defined message number
		cmp	edx, eax
		lodsd				; Pointer to application defined handler
		jz     .Handle
		loopnz	@B

	   @@:	or	rbx, rbx
		pop	rbx
		pop	rsi
		jnz    .Subed

		pop	rcx
		pop	rdx
		pop	 r8
		pop	 r9
		jmp	[ DefWindowProc ]

       .Subed:	mov	rcx, rbx
		pop	rbx			; lpPrevWndFunc
		pop	rsi
		pop	rdx			; hWnd
		pop	 r8			; Msg
		pop	 r9			; wParam
		pop	rax
		sub	rsp, 48
		mov	[ rsp + 32 ], rax      ; wParam
		jmp	[ CallWindowProc ]

      .Handle:	call	rax
		jc	@B			; Do default processing if specified

		add	rsp, 48 		; Waste everything on stack
		xor	rax, rax
		ret

		align	 16
; --------------------------------------------------------------------------------------------

  MainWndProc:	mov	eax, MMap
		jmp	ScanMap

		align	 8
; --------------------------------------------------------------------------------------------
;                                                                                   13BH - 315
	 Init:	push	rbp
		mov	rbp, rsp

		xor	ecx, ecx
		invoke	LoadIcon, rcx, IDI_APPLICATION
		or	eax, eax
		jnz	@F

		mov	rdx, Err001
		jmp	.Error

	   @@:	push	rax			; hIconSm
		push	AppName 		; lpszClassName
		push	 0			; lpszMenuName
		push	COLOR_WINDOW + 1	; hbrBackground

		push	rax			; Preserve what is handle to ICON
		xor	ecx, ecx
		invoke	LoadCursor, rcx, IDC_ARROW
		or	eax, eax
		jnz	@F

		mov	rdx, Err002
		jmp	.Error

	   @@:	xchg	[rsp], rax		; hCursor
		push	rax			; hIcon

		xor	ecx, ecx
		invoke	GetModuleHandle, rcx
		mov	[hInst], eax
		push	rax			; hInstance
		push	0			; cbWndExtra & cbClsExtra
		push	MainWndProc		; lpfnWndProc
		mov	eax, CS_OWNDC + CS_HREDRAW + CS_VREDRAW
		shl	rax, 32
		mov	 al, sizeof.WNDCLASSEX
		push	 rax			; cbSize & style

	; Register main window, stack is now pointing to WNDCLASSEX struct

		mov	rcx, rsp
		invoke	RegisterClassEx, rcx
		or	 ax, ax
		jnz	 @F
; 096 - 150
		mov	edx, Err003
		jmp	.Error

	STYLE	=    WS_VISIBLE + WS_SYSMENU + WS_MINIMIZEBOX
; --->
	   @@:	push	NULL			; lParam
		mov	eax, [hInst]
		push	rax			; hInstance

		invoke	LoadMenu, rax, IDM_MAINM
		or	eax, eax
		jnz	@F

		mov	edx, Err005
		jmp	.Error

	   @@:	push	rax			; hMenu
		push	NULL			; hWndParent

		push	600			; nHeight
		push	800			; nWidth

		mov	eax, CW_USEDEFAULT
		push	rax			; y
		push	rax			; x
		sub	rsp, 32

		mov	 r9, STYLE		; dwStyle
		mov	 r8, AppTitle		; lpWindowName
		mov	edx, AppName		; lpClassName
		mov	ecx, WS_EX_WINDOWEDGE	; dwExStyle
		call	[CreateWindowEx]

	; Don't worry about stack LEAVE is going to clean it up anyway

		or	eax, eax
		mov	edx, Err004
		jnz	.Exit
; 049 - 73

; --->
       .Error:	mov	 r9, MB_OK + MB_ICONSTOP
		mov	 r8, ErrCapt
		xor	 ecx, ecx
		invoke	MessageBox, ecx, edx, r8, r9

		stc				; So app will bounce over message pump
; 01F - 31

	.Exit:	mov	[ MainWnd ], eax	; Save copy of main windows handle
		leave				; Kill empty procedure frame
		ret

; --------------------------------------------------------------------------------------------

     Quit_App:	xor	ecx, ecx
		invoke	PostQuitMessage, rcx
		clc
		ret


		section '.data' data readable writeable
; ============================================================================================

	 hInst	dd	0
       MainWnd	dd	0

       AppName	db	'PE64V', 0
      AppTitle	db	'PE View 64', 0

       ErrCapt	db	'Initialization failure', 0
	Err001	db	'I C O N', 0
	Err002	db	'C U R S O R', 0
	Err003	db	'Registering main window', 0
	Err004	db	'Creating Main Window', 0
	Err005	db	'Main Menu', 0

		align	16

	  MMap	dd	0
		dd	( MMapEnd - $) / 8

		dd	WM_DESTROY
		dd	Quit_App
		dd	WM_COMMAND
		dd	MCmd
      MMapEnd:

	 MFunc	db	'Menu Function', 0
	  NotI	db	'Function not implemented', 0

		section '.rsrc' resource data readable
; ============================================================================================

       IDM_MAINM  =  48
	IDM_OPEN  = 128
	IDM_EXIT  = 196
	IDM_ABOUT = 200

  ; resource directory

  directory RT_MENU,menus

  ; resource subdirectories

  resource menus, IDM_MAINM, LANG_ENGLISH + SUBLANG_DEFAULT ,main_menu

  menu main_menu
       menuitem '&File',0,MFR_POPUP
		menuitem '&Open',IDM_OPEN
		menuseparator
		menuitem 'E&xit',IDM_EXIT,MFR_END
       menuitem '&Help',0,MFR_POPUP + 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'
