Win09.ASM : An Owned Window
;Win09.ASM : Creating An Owned Window (May 10, 2024)
%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 win09.asm -o win09.obj
;
; Linking: golink.exe /entry:start win09.obj win09.res kernel32.dll user32.dll
;===========================================================================
;This sample creates an OWNED window which,like the main window, is a top-level
;window. ;Note that the OWNED window doesn't have the WS_CHILD style. This allows
;the window to be created outside of the Client Area of the parent.
;If you want to see this for yourself, change the WNDCLASSEX style parameter of
;the owned window from:
;
; WS_OVERLAPPEDWINDOW +WS_VISIBLE,\
; to:
;
; WS_OVERLAPPEDWINDOW +WS_VISIBLE +WS_CHILD,\
;
;Now, the new window will be only partially visible inside the Client Area
; of the parent window. Clicking on the resize box of the PARENT sysmenu
; at the top right corner will expand the parent to full size and only then
; does the WS_CHILD window become entirely visible.
;
;The only other new wrinkle is changing the caption on the Message Box.
%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]
wcx times WNDCLASSEX_size db 0
wcxOwn times WNDCLASSEX_size db 0
msg times MSG_size db 0
;-----------------------------------------------------
;Define another WNDCLASSEX instance for the owned window
;-------------------------------------------------------
szTitle db 'win09 : NASM Sample To Create and Display An Owned Window',0x0
szClass db 'win09 Class',0x0
szTitleOwn db 'This Is The Owned Window. Esc Key or System Close ("X") To Close Window',0x0
szClassOwn db 'Owned Class',0,0
;---------------
;HANDLES
;----------------
hInstance dd 0
hWnd dd 0
hWndOwned dd 0
hMenu dd 0
;------------------
;MENU
;----------------
Win09_Menu equ 100
;IDM_SELECT equ 102
IDM_EXIT equ 104
IDM_OWNED equ 106
;------------------------
;MESSAGES
;--------------------------
MsgEndYesNo db "Close The Owned Window ?.",0
MsgBoxTitle1 db "Request For Termination",0
[section .text]
start: ;THIS LABEL IS FOR GOLINK.EXE.
proc win09
invoke GetModuleHandleA, dword NULL
mov [hInstance], eax
invoke WinMain,dword [hInstance],dword NULL,dword NULL,dword SW_SHOWNORMAL
invoke ExitProcess,dword NULL
ret
endproc ;win09
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]
mov eax,Win09_Menu
mov [wcx + WNDCLASSEX.lpszMenuName],eax
invoke RegisterClassExA, dword wcx
;----------------
;Create Main Window
;-----------------
invoke CreateWindowExA,\
WS_EX_OVERLAPPEDWINDOW,\
szClass,\
szTitle,\
WS_OVERLAPPEDWINDOW +WS_VISIBLE ,\
100, 120, 600, 232,\
NULL,\
dword [hMenu],\
dword [hInstance],\
NULL
mov [hWnd], eax
;-------------------------
;Process Windows Messages
;-------------------------
MsgGet:
invoke GetMessageA, dword msg, dword NULL, dword NULL, dword NULL
cmp eax,0
jnz MsgProcess
jmp MsgEnd
MsgProcess:
invoke TranslateMessage, dword msg
invoke DispatchMessageA, dword msg
jmp MsgGet
MsgEnd:
ret
endproc ;WinMain
;===========================================================================
;WndProc for main window
proc WndProc, hWin, uMsg, wParam, lParam
Is_Key?:
cmp dword argv(uMsg),dword WM_KEYDOWN
jz MsgKey
Is_Command?:
cmp dword argv(uMsg),WM_COMMAND
jz MsgCommand
Is_Destroy?:
cmp dword argv(uMsg),dword WM_DESTROY
jz Destroy
jmp DefWndProc
;WM_DESTROY
Destroy:
jmp ExitMainWin
;KEY STRUCK
MsgKey:
cmp argv(wParam), dword VK_ESCAPE ; ESC Key ?
jnz NotESCKey
jmp ExitMainWin ; ESC struck. Exit.
NotESCKey:
xor eax,eax ;Nothing of interest in WM_KEYDOWN.
ret
;-------------
;MENU COMMAND
;-------------
MsgCommand:
cmp dword argv(wParam),IDM_EXIT ; Menu exit request?
jnz MenuCreateOwned?
jmp ExitMainWin
MenuCreateOwned?:
cmp dword argv(wParam),IDM_OWNED ; Menu create new window request?
jz win09OwnedRequest
xor eax,eax
ret
;-------------------------------
;REQUEST TO OPEN A NEW WINDOW
;------------------------
win09OwnedRequest:
cmp dword [hWndOwned],0 ;Make sure the window hasn't already been opened.
jz win09OwnedRequest2
jmp win09OwnedRequest2Exit
win09OwnedRequest2:
;Populate another WNDCLASSEX structure.
push dword WNDCLASSEX_size
pop dword [ wcxOwn + WNDCLASSEX.cbSize]
push dword CS_VREDRAW +CS_HREDRAW
pop dword [ wcxOwn + WNDCLASSEX.style]
push dword WndProcOwned ; Adr of Owned WndProc
pop dword [ wcxOwn + WNDCLASSEX.lpfnWndProc]
push dword [hInstance]
pop dword [ wcxOwn + WNDCLASSEX.hInstance]
push dword COLOR_BTNFACE +1
pop dword [ wcxOwn + WNDCLASSEX.hbrBackground]
push dword szClassOwn
pop dword [ wcxOwn + WNDCLASSEX.lpszClassName]
invoke RegisterClassExA, dword wcxOwn ;Register the new window.
invoke CreateWindowExA,\
WS_EX_OVERLAPPEDWINDOW,\
szClassOwn,\
szTitleOwn,\
WS_OVERLAPPEDWINDOW +WS_VISIBLE,\
120, 140, 700, 240,\
dword argv(hWin),\
NULL,\
dword [hInstance],\
NULL
mov [hWndOwned], eax
win09OwnedRequest2Exit:
xor eax,eax
ret ;We handled the menu request so return and wait.
DefWndProc:
invoke DefWindowProcA, dword argv(hWin), dword argv(uMsg), dword argv(wParam), dword argv(lParam)
ret
;------------------
;EXIT PROCECURE
;------------------
ExitMainWin:
invoke PostQuitMessage,dword NULL
xor eax,eax
ret
endproc ;WndProc
;===========================================================================
;WndProc for OWNED window
proc WndProcOwned, hWinOwned, uMsgOwned, wParamOwned, lParamOwned
;Check for WM_CLOSE request.
cmp dword argv(uMsgOwned), dword WM_CLOSE
jnz wpoKeyDown?
wpoCloseFirstPass:
invoke MessageBoxA, dword argv (hWinOwned), MsgEndYesNo,MsgBoxTitle1, MB_YESNO
cmp eax, IDYES ;Yes =Close Window
jz wpoUserConfirmsDestroy
xor eax,eax
ret
;User confirms destroy window.
wpoUserConfirmsDestroy:
mov dword [hWndOwned],0
invoke SetFocus, dword [hWnd]
jmp DefWndProcOwned ;Pass WM_CLOSE to DefWndProc. This automatically
; destroys window.
;Check for a key strike
wpoKeyDown?:
cmp argv(uMsgOwned), dword WM_KEYDOWN
jz IsEscOwned?
jmp DefWndProcOwned ;No messages of interest for us.
;Key Strike: is ESC?
IsEscOwned?:
cmp argv(wParamOwned), dword VK_ESCAPE ; ESC Key ?
jz wpoEscChoice
xor eax,eax ;Only WM_KEYDOWN argument which interests us is ESC.
ret
;Send WM_CLOSE to system.
wpoEscChoice:
invoke SendMessageA, dword argv (hWinOwned),WM_CLOSE, NULL, NULL
xor eax,eax
ret
DefWndProcOwned:
invoke DefWindowProcA, dword argv(hWinOwned), dword argv(uMsgOwned), dword argv(wParamOwned), dword argv(lParamOwned)
ret
endproc ;WndProcOwned
;mcamember May 10, 2024