;Win10B.asm : RC Dialog /Edit Control /IsDialogMessage / DEFPUSHBUTTON/ (April 29, 2018)

;===================================================================
;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 Win10b.asm -o Win10b.obj
;       Linking:
;       GoLink.exe: golink.exe /entry:start Win10b.obj Win10b.res kernel32.dll user32.dll
;
;===================================================================

%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

hButton dd 0
hInstance dd 0
hWnd dd 0
hWndDlg dd 0
hMenu dd 0

;Equates

Menu_Win10B		equ 1000
IDM_DLGBOX      equ 1020
IDM_HELP        equ 1080

Dlg_Win10B       equ 2000
IDC_EDIT        equ 2010
IDC_DEFBUT      equ 2020

;Various labels

CountChar dd 0
szMenuName db "Menu_Win10B",0x0
szTitle db 'Win10B - Menu/Dialog With DefPushbutton',0x0
szClass db 'Win10B Class',0x0
DlgTxtBuf times 10h db "0"
lDlgTxtBuf equ $-DlgTxtBuf 	;not used. See Win10.rtf
 
                       [section .text]

     start:        

     proc Win10
       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]


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

	invoke CreateWindowExA,\
                 WS_EX_OVERLAPPEDWINDOW,\
                                szClass,\
                                szTitle,\
       WS_OVERLAPPEDWINDOW  +WS_VISIBLE,\
                     100, 120, 500, 232,\
                                   NULL,\
								   NULL,\
                       dword [hInstance],\
                                   NULL
              mov [hWnd], eax

     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 for dialog box.
           jnz MsgProcess    ; Not for dialog box. Feed it to Windows
        jmp MsgGet         
     
	 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.
;  When WM_CLOSE drops to DefWndProc the system will send us WM_DESTROY.

     proc WndProc, hWin, uMsg, wParam, lParam

        cmp dword argv(uMsg), WM_CHAR
			jnz IsCommand?
		cmp dword argv(wParam),VK_ESCAPE
			jnz near DefWndProc
			invoke SendMessageA,dword argv(hWin),WM_CLOSE,NULL,NULL
			jmp DefWndProc

        IsCommand?:             
		cmp dword argv(uMsg), WM_COMMAND
            jz near wpCommand
		cmp dword argv(uMsg), WM_DESTROY
            jz near ExitWin10B  
		jmp DefWndProc	;End of traps. Pass msg to DefWndProc

        wpCommand:
			cmp dword argv(lParam),0	;Not really necessary. Only a control will set lParam <>0
				jz IsDlgRequest?		;and there are no controls in the main window.
			jmp ExitWin10B				;Nothing in main win should set lParam <>0
IsDlgRequest?:
            cmp dword argv(wParam),IDM_DLGBOX
              jz wpCreateDlg
            xor eax,eax  ;Key handled. xor eax and return.
		ret
			wpCreateDlg:
            cmp dword [hWndDlg],0
				jz MakeDialog
				xor eax,eax	; hWndDlg<>0  =dialog is already running so bypass.
		ret
MakeDialog:
              invoke CreateDialogParamA,\
                 dword [hInstance],\
                         Dlg_Win10B,\
                  dword argv(hWin),\
                      DlgProc,\
                        dword NULL

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

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

          ExitWin10B: ;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 dialog
;  a WM_DESTROY message automatically after WM_CLOSE.

     proc DlgProc, hDlg, msgDlg,wParamDlg, lParamDlg

		cmp dword argv(msgDlg),WM_COMMAND
			jz dpCommand
		cmp dword argv(msgDlg),WM_CLOSE
			jz near dpClose        
		mov eax,FALSE
	ret		       

;WM_COMMAND message
	dpCommand:
		mov eax, dword argv(wParamDlg)
        cmp dword argv(lParamDlg),0 ; Needed here. We have a pushbutton control.
           jnz dplPNotZero
	dplPZero:
			cmp ax,IDCANCEL
				jz dpClose
			mov eax,TRUE
		ret

;WM_COMMAND/lParam <>0. Check wParam (LOWORD) for pushbutton ID
	dplPNotZero:
			cmp ax,IDC_DEFBUT
				jz dpBtnID
			mov eax,TRUE
		ret		 

;DefPushbutton pressed. Set focus to the edit box.
			dpBtnID:
				invoke GetDlgItem,dword argv(hDlg),IDC_EDIT
				invoke SetFocus, eax
                invoke GetDlgItemTextA, dword argv(hDlg),IDC_EDIT,\
                                             DlgTxtBuf,lDlgTxtBuf
;**********************************************************************************
;This next line can be substituted in place of the previous one. It has
;  the value (2010) of the Edit contrlol instead of the ID (IDC_EDIT).
;                invoke GetDlgItemTextA, dword argv(hDlg),2010,\
;                                             DlgTxtBuf,lDlgTxtBuf
;**********************************************************************************
				 mov dword [CountChar],eax
                 invoke GetDC,dword [hWnd]   ; Get DC for MAIN window.
push eax
                 invoke TextOutA,eax,0,0,DlgTxtBuf,dword [CountChar]
pop eax
                 invoke ReleaseDC, dword [hWnd], eax
				 mov eax,TRUE
		ret			

;Close program request.
             dpClose:
               invoke InvalidateRect,dword  [hWnd],0,1 ;Erase main window.
               invoke DestroyWindow,dword argv(hDlg) ;Kill dialog/edit box.
               mov dword [hWndDlg],0
               mov eax,TRUE
			ret

 endproc ;DlgProc


;mcamember May 10, 2024