Hi Everyone,


This small program of mine creates another window with its own WndProc. I'm trying to close both windows and terminate the program.
To close the second window i created, i used the CloseTwo method declared in window2.asm and it invokes DestroyWindow.
Although i can close both windows, the program does not get terminated. I need to go go to the Task Manager to end the process manually. Where did i go wrong?

window1.asm code:
-------------------------------------------------------------------------------------------------
include...
includelib...

include window2.asm

WinMain PROTO:DWORD,:DWORD,:DWORD,:DWORD

.data
ClassName DB "Window 1",0
AppName DB "Window 1",0
MenuName DB "WindowsMenu",0

.data?
hInstance HINSTANCE ?
CommandLine LPSTR ?

wwidth DWORD ?
wheight DWORD ?

twoCreated DWORD ?

.const
IDM_CREATE EQU 1

.code
start:
invoke GetModuleHandle, NULL
mov hInstance,eax

invoke GetCommandLine
mov CommandLine,eax

invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
invoke ExitProcess,eax

; #################### WinMain ####################
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc :WNDCLASSEX
LOCAL msg :MSG
LOCAL hwnd :HWND

mov wc.cbSize, SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra, NULL
mov wc.cbWndExtra, NULL
push hInstance
pop wc.hInstance
mov wc.hbrBackground, COLOR_BTNFACE+1
mov wc.lpszMenuName, OFFSET MenuName
mov wc.lpszClassName, OFFSET ClassName

invoke LoadIcon,NULL,IDI_APPLICATION
mov wc.hIcon, eax
mov wc.hIconSm, eax

invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor, eax

invoke RegisterClassEx,ADDR wc

mov wwidth, 380
mov wheight, 110

INVOKE CreateWindowEx,NULL,ADDR ClassName,
ADDR AppName,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,
wwidth,wheight,NULL,NULL,hInst,NULL
mov hwnd,eax

invoke ShowWindow, hwnd,SW_SHOWNORMAL
invoke UpdateWindow, hwnd

.while TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.break .if (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.endw

mov eax,FALSE
mov twoCreated,eax

mov eax,msg.wParam
ret
WinMain endp

; #################### WndProc ####################
WndProc proc uses ebx ecx edx esi edi,hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM

.if uMsg==WM_CREATE

.elseif uMsg==WM_COMMAND
mov eax,wParam
.if ax==IDM_CREATE
mov eax,TRUE
mov twoCreated,eax
invoke CreateTwo,hWnd,hInstance
.endif

.elseif uMsg==WM_DESTROY
mov eax,twoCreated
.if eax==TRUE
invoke CloseTwo
.endif
mov twoCreated,FALSE

invoke PostQuitMessage,NULL
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif

ret
WndProc endp

end start


window2.asm code:
-------------------------------------------------------------------------------------------------
CloseTwo PROTO

.data
ClassName2 DB "Window 2",0
AppName2 DB "Window 2",0

.data?
h_Win2 HWND ?

.code
; #################### CreateTwo ####################
CreateTwo proc hWin:HWND,hInstance:DWORD
LOCAL wc2 :WNDCLASSEX
LOCAL msg :MSG

mov wc2.cbSize, SIZEOF WNDCLASSEX
mov wc2.style, CS_HREDRAW or CS_VREDRAW
mov wc2.lpfnWndProc, OFFSET WndProc2
mov wc2.cbClsExtra, NULL
mov wc2.cbWndExtra, NULL
push hInstance
pop wc2.hInstance
mov wc2.hbrBackground,COLOR_BTNFACE+1
mov wc2.lpszMenuName,NULL
mov wc2.lpszClassName,OFFSET ClassName2

invoke LoadIcon,NULL,IDI_APPLICATION
mov wc2.hIcon, eax
mov wc2.hIconSm, eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc2.hCursor, eax

invoke RegisterClassEx,ADDR wc2

invoke CreateWindowEx,NULL,ADDR ClassName2,
ADDR AppName2,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,
280,110,NULL,NULL,hInstance,NULL
mov h_Win2,eax

invoke ShowWindow,h_Win2,SW_SHOWNORMAL
invoke UpdateWindow,h_Win2

.while TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.break .if (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.endw

mov eax,msg.wParam
ret
CreateTwo endp

; #################### WndProc2 ####################
WndProc2 proc uses ebx ecx edx esi edi,hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM

.if uMsg==WM_CREATE
.elseif uMsg==WM_COMMAND
.elseif uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
.else
invoke DefWindowProc,hWin,uMsg,wParam,lParam
ret
.endif

ret
WndProc2 endp

; #################### CloseTwo ####################
CloseTwo proc uses eax
invoke DestroyWindow,h_Win2
ret
CloseTwo endp

-----------------------

Thanks.
Posted on 2004-04-19 07:21:52 by trexxz
Although you create 2 windows the message loop has to be only one. In CreateTwo procedure you don't need the .while .endw block. The main message loop will catch messages for both windows and call WndProc or WndProc2 accordingly.
Posted on 2004-04-19 07:40:48 by Vaxon
Thanks Vaxon!

Now i can close both window 1 and 2 when i close 1. But now i can't keep window 1 open when i close window 2...
How do i keep window 1 open although window 2 is closed?
Posted on 2004-04-19 20:45:58 by trexxz
Does it mean that i need 2 message loops?
Posted on 2004-04-19 20:48:38 by trexxz
If you don't want the program to quit when you close window 2, don't call PostQuitMessage in window 2.
Posted on 2004-04-19 22:02:09 by tenkey

How do i keep window 1 open although window 2 is closed?


You can handle the WM_CLOSE of win2, no close the win2 but hide the win2.


.ELSEIF uMsg == WM_CLOSE
;-------------------------
; Hide the win2 when user close the win2
;-------------------------
invoke ShowWindow, hWnd, SW_HIDE


and close the program when user close win1.

please take a look into the attached archive.
Posted on 2004-04-19 22:36:26 by purpleendurer
Got it!

Thank you tenkey and purpleendurer. :grin:
Posted on 2004-04-20 00:28:09 by trexxz