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