使用Win32 API验证HWND

时间:2010-02-26 19:24:13

标签: c++ winapi

使用C ++从本机Win32 API可以确定与HWND关联的窗口是否仍然有效?

7 个答案:

答案 0 :(得分:30)

您可以使用Win32 API IsWindow

不建议使用它,原因有两个:

  1. 窗口被破坏后可以重复使用Windows句柄,因此您不知道是否有完全不同窗口的句柄。
  2. 状态可能会在此次通话后直接更改,您会认为它有效,但可能无效。
  3. 来自MSDN(与上面相同的链接):

      

    线程不应该使用IsWindow   它没有创建的窗口,因为   之后窗户可能会被摧毁   这个功能被调用了。进一步,   因为窗户把手是回收的   手柄甚至可以指向一个   不同的窗口。

    可以做些什么?

    也许您的问题可以重新设计,因此您无需检查有效的句柄。例如,您可以建立从客户端到服务器的管道。

    您还可以创建一个Windows挂钩来检测某些消息何时发生,但这对于大多数需求来说可能有点过分。

答案 1 :(得分:11)

这个问题很老,但我自己需要这个功能,在阅读了有关警告后有点失望。然而,在做了一点挖掘后,似乎一切都很顺利。除非你正在处理16位程序,否则IsWindow似乎是要走的路。手柄重复使用的问题似乎已经充分解决了这个问题:

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

因此,由于高16位重用计数器,您不太可能遇到窗口重用问题。

答案 2 :(得分:8)

您可以使用IsWindow()或尝试向窗口发送带有SendMessage(hWnd,WM_NULL)的WM_NULL消息,并查看它是否成功。

此外,如果窗口不在您的控制范围内,则可以随时销毁窗口。正如其他人所说,当句柄被重用时,句柄可能属于另一个窗口。实际上我不知道那有多大可能。

我知道创建系统范围hook的唯一解决方案,用于查找指示窗口被破坏的消息(WM_CLOSE,WM_DESTROY)。然后,您将比较消息窗口句柄与您持有的句柄,以查看您关心的任何窗口是否受到影响。 See here for more information on system wide hooks.

答案 3 :(得分:1)

答案 4 :(得分:1)

如果相关窗口的窗口过程在您的控制之下(或者您可以将其子类化),那么我建议注册窗口响应的自定义消息,其结果为非零。将该消息发送到任何其他窗口(或无效的HWND)将导致0。

当然,这只会告诉您HWND是否引用了您控制的其中一个窗口 - 但也许会给出上面的其他答案,甚至可能是有利的。

使用RegisterWindowMessage使用足够唯一的名称注册邮件。

答案 5 :(得分:1)

也许IsWindowFindWindowGetWindowThreadProcessId的组合会更准确

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

答案 6 :(得分:0)

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

将检查窗口是否存在并具有相应的名称