tags:

views:

457

answers:

3

From the native Win32 API using C++ is there a way to determine whether the window associated with an HWND is still valid?

+5  A: 

You can use IsWindow() or also try to send the window a WM_NULL message with SendMessage(hWnd, WM_NULL) and see if it is successful.

Also, it is true that the window could be destroyed at any time if it isn't under your control. As others have stated the handle could potentially belong to another window as the handles are reused. In reality I don't know how likely that is.

The only solution that I know of the to create a system wide hook that looks for messages indicating a window is destroyed (WM_CLOSE, WM_DESTROY). Then you would compare the message window handle to ones you are holding to see if any of the windows you care about are affected. See here for more information on system wide hooks.

Dana Holt
Sending a WM_NULL message may not be a good idea. Some apps actually perform operations in response to WM_NULL messages.
Remy Lebeau - TeamB
+2  A: 

IsWindow

Nemanja Trifunovic
+10  A: 

You could use the Win32 API IsWindow.

It is not recommended to use it though for 2 reasons:

  1. Windows handles can be re-used once the window is destroyed, so you don't know if you have a handle to an entirely different window or not.
  2. The state could change directly after this call and you will think it is valid, but it may really not be valid.

From MSDN (same link as above):

A thread should not use IsWindow for a window that it did not create because the window could be destroyed after this function was called. Further, because window handles are recycled the handle could even point to a different window.

What can be done?

Perhaps your problem can be re-architected so that you do not have the need to check for a valid handle. Maybe for example you can establish a pipe from the client to the server.

You could also create a windows hook to detect when certain messages occur, but this is probably overkill for most needs.

Brian R. Bondy
What would be a solution then?
Vlad
@Vlad: That depends on what you're trying to accomplish.
Brian R. Bondy
@Brian: to determine whether the window associated with an HWND is still valid?
Vlad
@Vlad: I got that much, but I mean what do you want to do after that. Also that's my point, once you know and you get to your next line of code, that assumption will already be broken because it may already be closed and a new one could even be opened.
Brian R. Bondy
It was worth a try, but the window owned by another process can still go invalid after the IsWindow call and cause a problem. I will look for other solutions.
Doug Ferguson
You need to know the behavior of the window in question. Is this window running in the same thread as the function that is asking IsWindow? If you can guarantee that the window cannot be closed while you're investigating its HWND, then you're okay. If you cannot - truly independent threads, then you've a real design issue on your hands, and you need to rethink what you're trying to do (big picture), and rearchitect things so that you know when that HWND is valid due to the design of your software.
Mordachai
@Vlad: 1 - avoid storing window handles. 2 - if you must store a window handle, make sure you can invalidate that store when the WM_CLOSE or WM_DESTROY for the window occurs.
Steve314
@Vlad and @Steve314: yes you could do this via Windows hooks for a different process, but there may be a simple solution to completely avoid this depending on the callers need.
Brian R. Bondy
Added a bit more to the answer to make those points. Thanks @Vlad and @Steve314
Brian R. Bondy
@Brian: I understand that a window which I don't control myself can be destroyed even before the moment the stack is cleaned up after function call. But for me the correct answer to the question was interesting, not the reason why the question itself is "bad" (the latter I understand myself).
Vlad
@Brian: after the edit it's more clear, thanks!
Vlad
I didn't see Dougs comment before I wrote mine - should have refreshed. I still had the idea that it was inside one process. Since Brian found sense in it anyway, I'm half tempted to keep quiet, but I guess confession is good for the soul.
Steve314