Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validate HWND using Win32 API

Tags:

c++

winapi

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

like image 447
Doug Ferguson Avatar asked Feb 26 '10 19:02

Doug Ferguson


People also ask

How do you check window handles?

However, you can obtain the window handle by calling FindWindow() . This function retrieves a window handle based on a class name or window name. Call GetConsoleTitle() to determine the current console title. Then supply the current console title to FindWindow() .

Is Hwnd a pointer?

HWNDs are essentially pointers (IntPtr) with values that make them (sort of) point to a window-structure data. In general HWNDs are part an example for applying the ADT model.

What is WinAPI in C?

The Windows API, informally WinAPI, is Microsoft's core set of application programming interfaces (APIs) available in the Microsoft Windows operating systems.


5 Answers

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.

like image 71
Brian R. Bondy Avatar answered Oct 24 '22 09:10

Brian R. Bondy


This question is old, but I needed this functionality myself and was a bit disappointed after reading about the caveats. However, after doing a bit more digging it seems that all is well. Unless you're dealing with 16bit programs, IsWindow appears to be the way to go. The problem of handle re-use appears to have been sufficiently addressed according to this:

http://blogs.msdn.com/b/oldnewthing/archive/2007/07/17/3903614.aspx

So, because of the upper 16bit reuse counter, it is highly unlikely that you'll run into a window reuse problem.

like image 31
Yap Dog Avatar answered Oct 24 '22 09:10

Yap Dog


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.

like image 20
TWA Avatar answered Oct 24 '22 10:10

TWA


Maybe a combination of IsWindow, FindWindow and GetWindowThreadProcessId will be more accurate

HWND windowHandle = FindWindow(NULL, TEXT("window_title"));
LPDWORD oldpid = 0;
GetWindowThreadProcessId(windowHandle, &oldpid);
//after some time
if (IsWindow(windowHandle))
{
    LPDWORD newpid = 0;
    GetWindowThreadProcessId(windowHandle, &newpid);
    if (newpid == oldpid)
    {
        //the window is still running
    }else
    {
        //the window exists but has changed
    }
}
like image 4
IdontCareAboutReputationPoints Avatar answered Oct 24 '22 09:10

IdontCareAboutReputationPoints


If the window procedure for the window in question is under your control (or if you can subclass it), then I would suggest registering a custom message that the window responds to with a non-zero result. Sending that message to any other window (or an invalid HWND) will result in 0.

Of course, that only tells you if the HWND refers to one of the windows that you control -- but perhaps given other answers above that might even be advantageous.

Use RegisterWindowMessage to register the message, using a sufficiently unique name.

like image 1
Chip Camden Avatar answered Oct 24 '22 08:10

Chip Camden