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.
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.
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.
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?
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?
Does it mean that i need 2 message loops?
If you don't want the program to quit when you close window 2, don't call PostQuitMessage in window 2.
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.
Got it!
Thank you tenkey and purpleendurer. :grin:
Thank you tenkey and purpleendurer. :grin: