I was messing around with a PeekMessage message loop today, and here was my original design:
.WHILE TRUE
invoke PeekMessage, ADDR msg,hwnd,0,0,PM_REMOVE
.IF eax != 0
.BREAK .IF (msg.message == WM_QUIT)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDIF
invoke Beep, 16000, 200 ; doing something every time
.ENDW
Whenever I used this code, it would work but the program would never end. It would close the window, but the message loop/beep would go on endlessly till I shut it down. After reading up on PeekMessage, i noticed the following:
QuotePeekMessage retrieves only messages associated with the window identified by the hWnd parameter
and
QuoteIf hWnd is NULL, PeekMessage retrieves messages for any window that belongs to the current thread making the call.
so I changed the function call to PeekMessage, ADDR msg,
NULL,0,0,PM_REMOVE, and it seems to work fine.
So why is that? I only have one window registered (hwnd), no child windows, no nothing; Apparently WM_QUIT is not 'associated with the window identified by hWnd'? What else would it be associated with?
thanks as always
alan
the WM_QUIT message cannot be processed if it's not posted.
The message loop is just the one side of the medal :)
In you WindowProcedure you have to post the WM_QUIT message, using PostQuitMessage(0) where 0 is the wParam of the posted WM_QUIT message, i.e.:
WndProc PROC hwnd:HWND,uMsg:DWORD,wParam:DWORD,lParam:DWORD
.if uMsg == WM_CLOSE
invoke PostQuitMessage,NULL
.endif
invoke DefWindowProc,hwnd,uMsg,wParam,lParam
ret
WndProc ENDP
WM_CLOSE -> WM_DESTROY -> WM_QUIT.
This sequence is the full processing when closing window.
There are a lot of messages not seen to the programmer that processed by default. It is useful to look in OllyDbg put a breakpoint on window proc and with pencil and paper write them down when the window initialized and utilized... I bet you'll find a lot of interesting such as Non client area drawing messages... etc.
The WM_QUIT message is not associated with a window and is never received through a window's window procedure. Which means that posting it with PostQuitMessage will cause only GetMessage or PeekMessage to retrieve it. I couldn't really get your point, asmfan.
The WinProc for the same program (both ways) was
.IF uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
Is this not the 'accepted' way to do things (ie, DESTROY vs CLOSE vs QUIT)? What I was infering from the API reference was that using PeekMessage with hWnd was discarding the WM_CLOSE message altoghter (never calls the WinProc at all), but using it with NULL made PeekMessage pick up and process them (properly closes). After all, a "Window Close" message intuitivley seems like it should be associated with the window it's closing (hWnd).
Basically, I click the 'X' in the corner, and a WM_CLOSE gets posted, which the system uses to phsyically get rid of the window, then a WM_DESTROY gets posted, which my program uses soley to post the WM_QUIT, which the message loop detects to exit the message loop and end the execution? Something like that?
Times like these I miss INT 21 :'( Thanks again for un-dumbening me