开发者

Validate HWND using Win32 API

开发者 https://www.devze.com 2022-12-21 04:24 出处:网络
From开发者_StackOverflow the native Win32 API using C++ is there a way to determine whether the window associated with an HWND is still valid?You could use the Win32 API IsWindow.

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


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.


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.


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.


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
    }
}


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.


if(IsWindow(FindWindow(NULL , TEXT("Example Window Name")))){
     // do stuff
 }

will check if the window exists and has the appropriate name

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号