;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