;Win10A.asm : RC Dialog /Edit Control/IsDialogMessage - NO DefPushbutton (October 26, 2023)

%ifdef
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 -E asmerror Win10A.asm -o Win10A.obj
    Linking:
    GoLink.exe: golink.exe /entry:start Win10A.obj Win10A.res kernel32.dll user32.dll

===================================================================
%endif

%include '\nasm32\inc\win32\windows.inc'
%include '\nasm32\inc\win32\kernel32.inc'
%include '\nasm32\inc\win32\user32.inc'
%include '\nasm32\inc\win32\gdi32.inc'
%include '\nasm32\inc\nasm32.inc'

                             [section .data]

;Strucs

wcx times WNDCLASSEX_size db 0
msg times MSG_size  db 0

;Handles

hInstance dd 0
hWnd dd 0
hWndDlg dd 0

;Equates
Menu_Win10A EQU 1000
IDM_DLGBOX      equ 1020
IDM_HELP        equ 1080

Dlg_Win10A       equ 2000
IDC_EDIT        equ 2010

IDM_MENU    equ 2020

;Various labels
countChar dd 0
szMenuName db "Menu_Win10A",0x0
szTitle db 'Win10A - /Dialog/Edit/No DefPushbutton',0x0
szClass db 'Win10A Class',0x0
DlgTxtBuf times 10h db "0"
lDlgTxtBuf equ $-DlgTxtBuf


                         [section .text]

     start:        

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

     proc WinMain ,hInst,hPinst,CmdLn,dwShow

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

;A different method of populating memory slots.
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]


;When the array wcx is created the system fills it with zeroes and
;_LoadWCX doesn't overwrite lpszMenuName with any value. This is to
; keep the macro as a quick generic tool.
;Note that the hMenu parameter of CreateWindowEx stays as NULL.

		push dword Menu_Win10A
		pop dword [wcx +WNDCLASSEX.lpszMenuName]
        
        invoke RegisterClassExA, dword wcx

;Create the window
         invoke CreateWindowExA,\
          WS_EX_OVERLAPPEDWINDOW,\
                         szClass,\
                         szTitle,\
               WS_OVERLAPPEDWINDOW  +WS_VISIBLE,\
                 100, 120, 600, 232,\
                               NULL,\
								NULL,\
                     dword [hInstance],\
                              NULL

              mov [hWnd], eax

;Process windows messages
     MsgGet:
        invoke GetMessageA, dword msg, dword NULL, dword NULL, dword NULL
        cmp eax,0
           jnz MsgDlgCheck
       jmp MsgEnd
     MsgDlgCheck:
        invoke IsDialogMessageA,dword [hWndDlg], msg
        cmp eax,TRUE      ; TRUE =message from dialog box.
           jz MsgGet      ;Is from dialog box. DON'T feed it back to Windows.                               ; Get next message
     MsgProcess:
         invoke TranslateMessage, dword msg
         invoke DispatchMessageA, dword msg
         jmp MsgGet
		MsgEnd:
     ret
     endproc
;-------------------------------------------------------
;Windows callback function
;We don't trap for WM_CLOSE because we don't have any need
;  to interrupt the process of destroying the window.

      proc WndProc, hWin, uMsg, wParam, lParam

      cmp dword argv(uMsg), WM_COMMAND
        jz near wpMenu
      cmp dword argv(uMsg), WM_CHAR
        jz near IsChar
      cmp dword argv(uMsg), WM_DESTROY
        jz near ExitWin10A
      jmp DefWndProc	;End of traps. Pass msg to DefWndProc

        wpMenu:                    
		cmp dword argv(wParam),IDM_DLGBOX	;lParam value ignored. Only menu and
			jz wpIsRunning?					; accelerator keyhits in main win.
		xor eax,eax
		ret
          
          wpIsRunning?:
            cmp dword [hWndDlg],0	;hWndDlg =0 if dialog not already loaded.
              jz near wpCreateDlg
          xor eax,eax				;Dialog already loaded so bypass.
		  ret

          wpCreateDlg:
             invoke CreateDialogParamA,\
             dword [hInstance],\
                    Dlg_Win10A,\
              dword argv(hWin),\
                       DlgProc,\
                   dword NULL

         mov dword [hWndDlg],eax
         xor eax,eax
		 ret

        IsChar:
		cmp dword argv(wParam),VK_ESCAPE
			jz IsEsc
		xor eax,eax
		ret
			IsEsc:
				invoke SendMessageA,dword argv(hWin),WM_CLOSE,NULL,NULL
				xor eax,eax ;Win10A doesn't TRAP for WM_CLOSE so any request to 
			ret				;end the application results in an immediate shut-down.

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

;Exit procecure
        
        ExitWin10A: ;Quit the application
          invoke PostQuitMessage,dword NULL
          xor eax,eax
          ret
      endproc	;WndProc

;--------------------------------------------------------------
;Dialog callback function
;Here, we MUST trap WM_CLOSE because DefDlgProc doesn't send a WM_DESTROY
; message to a dialog box automatically after WM_CLOSE.

	proc DlgProc, hDlg, msgDlg,wParamDlg, lParamDlg

	IsCommand?:
		cmp dword argv(msgDlg),WM_COMMAND
			jz near dpCommand

		cmp dword argv(msgDlg),WM_CLOSE
			jz near dpClose        
		mov eax,FALSE   ; Dlg proc returns FALSE if message not handled.
		ret
          
	dpCommand:
		mov eax, dword argv(wParamDlg)
		cmp dword argv(lParamDlg),0	;This isn't really necessary. Menu +NO pushbutton
			jz dplPZero				; always reports 0 in lParam.
		mov eax,TRUE
	ret		
dplPZero:
		cmp ax,IDOK	;if enter key + no defpushbutton then wParam(LOWORD) =IDOK
			jz dpDefBut			
	IsDlgEsc?:
		cmp ax,IDCANCEL	;Esc.
			jz dpClose
		mov eax,TRUE
		ret
			dpDefBut:			
			;Which control has focus		
			invoke GetFocus
			invoke GetDlgCtrlID,eax
			cmp ax,IDC_EDIT
				jz dpText	;If Edit has focus then continue. Otherwise leave.
			mov eax,TRUE	;We handled WM_COMMAND
		ret

	dpText:
		invoke GetDlgItemTextA, dword argv(hDlg),IDC_EDIT, DlgTxtBuf, lDlgTxtBuf
		mov dword [countChar],eax
		invoke GetDC,dword [hWnd]   ; Get Device Context for MAIN window.
	push eax
		invoke TextOutA,eax,0,0,DlgTxtBuf,dword [countChar]
	pop eax
		invoke ReleaseDC, dword [hWnd], eax
			mov eax,TRUE
	ret

	dpClose:
	invoke InvalidateRect,dword  [hWnd],0,1 ;Erase main window.
	mov eax, dword [hWndDlg]	
	invoke DestroyWindow,dword argv(hDlg) ;Kill dialog/edit box.
	mov dword [hWndDlg],0  ;So we can keep making new dialogs as the old ones
								; are destroyed.
	mov eax,TRUE
	ret
      endproc ;DlgProc

;mcamember May 10, 2024