As a follow-up to my earlier thread concerning changing the color of a window I would like to destroy the brush used to change the window color at the termination of the process.

Donkey's help saved the day as usual, but his example does not save the brush handle and therefore it is not destroyed at the termination of the process.

F0dder says that the handle should be destroyed in order to avoid a memory leak. Others say that the handle will be automatically be destroyed by windows.

I tried an experiment using a message box to see if child windows are sent the WM_DESTROY message at shutdown of the process. The results are that if the child window with the trap is closed, the event occurs, but if the parent window is closed (thus shutting down the process, the child window is not sent the message.

Is there any message that is sent to all windows before the process shuts down?
Posted on 2004-06-30 22:10:30 by msmith
I also tried WM_CLOSE instead of WM_DESTROY with the same result.
Posted on 2004-06-30 22:42:25 by msmith
Hi Mike,

My tests show that WM_DESTROY is sent to each child window in turn, see the attached file...
Posted on 2004-06-30 23:00:36 by donkey
Hi Donkey,

Here is the code snippet of my test (last modified to check for WM_CLOSE).

I get the message box when closing the test child window (!Window2) but not when closing the parent.



cmp [wmsg],WM_DESTROY
je !Window2DefWndProc
cmp [wmsg],WM_CLOSE
jne hook
invoke MessageBox,[OBMain],[sst1],[sst1],MB_OK
hook:


(Each child has its own WindowProc.)
Posted on 2004-06-30 23:06:57 by msmith
Hi Mike,

That is essentially the same as mine, I updated the executable to show a message box as I was using a debug lib that you probably don't have. The attachment in my post now displays a message box with the child windows class name in it. Every control on the dialog receives a WM_DESTROY in turn.

MSDN WM_DESTROY
The WM_DESTROY message is sent when a window is being destroyed. It is sent to the window procedure of the window being destroyed after the window is removed from the screen.

This message is sent first to the window being destroyed and then to the child windows (if any) as they are destroyed. During the processing of the message, it can be assumed that all child windows still exist.
Posted on 2004-06-30 23:11:43 by donkey
Hi Mike,

I just realized that you could be talking about different windows and not controls so I checked with those as well and the WM_DESTROY is always sent as well. Here is the demo. Note that the child sends a WM_CLOSE to the main and does not call PostQuitMessage, that is only for the main window to call, no other should do it.
Posted on 2004-06-30 23:50:57 by donkey
Hi Donkey,

Since the docs you quote say that message is sent first to the window being destroyed and then to the child windows...

It would seem that my event handler for the parent window is messing me up. it is:



!wmDestroy:
invoke DeleteObject,[!Brush]
invoke PostQuitMessage,0
xor eax,eax

!Finish:
pop edi esi ebx
return


BTW the brush in the snippet has nothing to do with the brush mentioned earlier in the post.

Edited Note:
I posted this reply not having seen your last response beforehand.

It looks like your exit code is similar to mine, so I don't know where my problem is.
Posted on 2004-06-30 23:52:02 by msmith
Hi Mike,

One last quick demo, this one uses CreateWindowEx.

Scratch that the WM_DESTROY definitely goes to the main window then it's children.
Posted on 2004-07-01 00:28:52 by donkey
Hi, Donkey,

My CreateWindowEx for each window is a little different than yours.




invoke CreateWindowEx,0,!OBMainClass,!title,WS_VISIBLE+WS_OVERLAPPEDWINDOW,0,0,400,300,NULL,NULL,[!hinstance],!OBMain
...

invoke CreateWindowEx,0,!Window2Class,!title,WS_VISIBLE+WS_OVERLAPPEDWINDOW,dword [edi+16], dword [edi+20], dword [edi+24], dword [edi+28], dword [OBMain],NULL,[!hinstance],!Window2



I know that the code (shown earlier) is at least somewhat working because I do get the msgbox when closing the child.
Posted on 2004-07-01 00:41:48 by msmith
Hi Mike,

I can't see anything wrong with the CreateWindowEx from your code, WS_OVERLAPPEDWINDOW is essentially the same as I used but it combines the caption and sysmenu styles into one. The extended style is not important in this case and can be ignored. I can't really say what might be wrong, every test I tried had both windows and every control receiving the WM_DESTROY, I can only say that there must be something up in your code that is causing your difficulty. Using your exact window styles I get the same results, the WM_DESTROY is sent to both windows. I would suspect that the message loop is returning before the second window gets it's message, that would mean usually that PostQuitMessage is being executed by a child window.
Posted on 2004-07-01 00:53:40 by donkey

I get the message box when closing the test child window (!Window2) but not when closing the parent.



cmp [wmsg],WM_DESTROY
je !Window2DefWndProc
cmp [wmsg],WM_CLOSE
jne hook
invoke MessageBox,[OBMain],[sst1],[sst1],MB_OK
hook:
You can't tell whether WM_DESTROY is sent or not with this code. The message box pops up only when WM_CLOSE is sent.

If you close the child with the X button, you get WM_CLOSE, and the message box appears.
If you close with parent, you don't get WM_CLOSE, and you can't tell whether you went to DefWndProc or hook.

Actually, the close button is a bit more complex.

X button --> WM_SYSCOMMAND, SC_CLOSE
DefWindowProc (WM_SYSCOMMAND) --> WM_CLOSE
DefWindowProc (WM_CLOSE) --> DestroyWindow
DestroyWindow --> messages for removing window from screen
DestroyWindow --> WM_DESTROY
DestroyWindow --> DestroyWindow (child window)
Posted on 2004-07-01 01:36:45 by tenkey

You can't tell whether WM_DESTROY is sent or not with this code. The message box pops up only when WM_CLOSE is sent.


Hi Tenkey,

That code was for WM_CLOSE...

Here is the code snippet of my test (last modified to check for WM_CLOSE).
Posted on 2004-07-01 01:43:54 by donkey
Well, I hope the sequences of events is more revealing. It would help to see the test for WM_DESTROY. Not yours, donkey, but msmith's.
Posted on 2004-07-01 02:00:15 by tenkey
tenkey,

Here it is:



proc !Window2Proc,!hwnd,wmsg,wparam,lparam
enter
push ebx esi edi
mov [!PassSystemEvent],0
cmp [wmsg],WM_GETMINMAXINFO
jne Window2NotwmGetMaxInfo
mov dword edi,[!hwnd]
mov dword [!Window2+44],edi
mov dword [!Window2+8],0
jmp !DefWndProc
Window2NotwmGetMaxInfo:
mov esi,!Window2
cmp [wmsg],WM_DESTROY
jne hook
invoke MessageBox,[OBMain],[sst1],[sst1],MB_OK
jmp !Window2DefWndProc
hook:
jmp !WinProcCommon
!Window2DefWndProc:
jmp !DefWndProc
Posted on 2004-07-01 09:23:19 by msmith
Donkey,

There are 3 cases of PostQuitMessage in the program.

The first is in the parent window's WM_DESTROY.

The second is in the code if an END statement is encountered.

The third is in the code if the program runs to the end with no END statement.

The last 2 never occur.

Mike
Posted on 2004-07-01 09:41:43 by msmith
Hi Donkey,


Donkey,

There are 3 cases of PostQuitMessage in the program.

The first is in the parent window's WM_DESTROY.

The second is in the code if an END statement is encountered.

The third is in the code if the program runs to the end with no END statement.

The last 2 never occur.

Mike


Wrong!

The second case occurs when the user hits the exit button (whose event contains an END statement)

I changed the the PostQuitMessage to "invoke PostMessage,,WM_CLOSE,0,0" and all is well.

Thanks to all of you for the help.
Posted on 2004-07-01 12:38:12 by msmith
Good to hear you got it worked out Mike, I suspected that it was the problem but it would have been alot of code to go through. And I still haven't gotten around to setting up FASM, downloaded it but other things keep diverting my attention. I have a fairly short attention sp.... hey shiny things :)
Posted on 2004-07-01 13:12:37 by donkey
Hi Donkey,

This was an example of what happens when I work when I'm too tired to think right.

Now, any OmniBasic generated code will have one and only PostQuitMessage is each program.

Thanks again,

Mike
Posted on 2004-07-01 13:55:57 by msmith
Have you guys tested this code on all flavours of Windows? I personally don't believe in letting the OS handle 'memory leak' cleanup situations! I believe they were forced to help sloppy developers so their OS wouldn't be blamed for sucking the machine dry! If you want something done properly ... do it yourself!
Posted on 2004-07-02 00:50:03 by SubEvil
Not sure about Mike but I tested mine on NT4, Win95 and Win2K.
Posted on 2004-07-02 00:54:46 by donkey