;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