From: twbrown@PE-Nelson.COM (Tom W. Brown)
Newsgroups: comp.os.ms-windows.programmer.misc
Subject: Re: how to find parentless non-child windows?
Date: 21 Dec 92 19:00:31 GMT
Organization: PE-Nelson

In article <1992Dec19.022439.8466@emr1.emr.ca>, jagrant@emr1.emr.ca (John Grant) writes:
|> My app behaves a bit like a MDI app, but not quite.  From the main
|> window, several other parentless non-child windows can be created as
|> follows:
|> 	CreateWindow("xxx",NULL,
|> 			WS_OVERLAPPED  | WS_CAPTION    |
|> 			WS_SYSMENU     | WS_THICKFRAME |
|> 			WS_MINIMIZEBOX | WS_MAXIMIZEBOX,
|> 			CW_USEDEFAULT,CW_USEDEFAULT,
|> 			CW_USEDEFAULT,CW_USEDEFAULT,
|> 			NULL,           //note - no parent
|> 			NULL,                           
|> 			hinstance,(LPVOID)xxx);
|> 
|> Note: they have *no parent* and they are *not* WS_CHILD.
|> 
|> When I close the application from the main window, these secondary
|> windows do not receive WM_DESTROY (I breakpointed WM_DESTROY and
|> it never gets there).  I guess the main window only sends WM_DESTROY
|> messages to them if they have a parent and/or if they are WS_CHILD?
|> Is that right?

Yes, well, only if they can trace ancestry to your main window -- they
certainly don't have to have WS_CHILD style and giving a window WS_CHILD
style without also giving it a parent won't cause it to be destroyed
automatically (granted, it doesn't make a lot of sense to do this).

Remember WS_CHILD is a _style_, it indicates how the window should be
handled in terms of clipping within the bounds of a parent.  It does not
establish a parent/child window relationship.  The two are really
independent.


|> 
|> So, when I process WM_DESTROY for the main window, I want to find
|> all of the secondary windows and shut them down too (so they can
|> de-allocate their resources).  I tried doing this when I get
|> WM_DESTROY for the main window:
|> 
|>   void DestroySecondaryWindows(void){
|>   HWND hwnd;
|> 	while((hwnd=FindWindow("xxx",NULL)){
|> 	  SendMessage(hwnd,WM_DESTROY,0,0);
|> 	}
|> 	return;
|>   }
|> 
|> Well, close but not quite.  The secondary window receives several
|> WM_DESTROY messages, even though I am using 'Send' instead of 'Post'.
|> I guess I need to wait until each window is destroyed before I
|> try to 'find' another one?  If so, how?  

Try "DestroyWindow(hwnd)" instead of sending a destroy message -- this still
may suffer from the timing problem, I don't know.

You may want to simply keep the handles for these windows in your app, in
a static HWND array, or somewhere.  Then you could simply loop through and
destroy them without having to "Find" them and worry about the timing in
the above loop.  I really can't think of a good reason not to do this.

You may also want to consider making them parented windows (but not WS_CHILD
windows) in order to have them automatically deleted when the application
is closed.

The last option I can think of would be to enumerate the windows (EnumWindows
instead of FindWindow), use GetClassName() on each to see if it belongs
to class "xxx", and use DestroyWindow() on those that are.


|> 
|> I had a glance at GetWindow, but I'm a bit confused by it - should
|> I be using GetWindow instead of FindWindow?  The problem is that the
|> secondary windows have *no parent*.

No, as you've discovered, GetWindow relies on a parent/child relationship
between windows and doesn't work for the same reason that the secondary
windows don't go away when you close the main window.



----------------------------------------------------------------------------
Tom Brown               |  "She turned me into a newt...
PE Nelson Systems       |                                  ... I got better"
twbrown@pe-nelson.com   |                    Monty Python and the Holy Grail
----------------------------------------------------------------------------
Newsgroups: comp.windows.ms.programmer,comp.os.ms-windows.programmer.misc