使用Win32 API验证HWND

Dou*_*son 18 c++ winapi

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

Bri*_*ndy 32

您可以使用Win32 API IsWindow.

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

  1. 窗口被破坏后,Windows句柄可以重复使用,因此您不知道是否有完全不同窗口的句柄.
  2. 在调用之后状态可以直接改变,你会认为它是有效的,但它可能真的无效.

从MSDN(与上面相同的链接):

线程不应该将IsWindow用于它没有创建的窗口,因为在调用此函数后窗口可能会被销毁.此外,由于窗口把手被回收,手柄甚至可以指向不同的窗口.

可以做些什么?

也许您的问题可以重新设计,这样您就不需要检查有效的句柄.例如,您可以建立从客户端到服务器的管道.

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


小智 12

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

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

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

  • 你应该引用那篇文章中重复的重点."此处描述的行为属于"实施细节"类别,可随时更改" (3认同)
  • "不太可能"与"不可能"不同.高位标记是为了减轻编程错误.这不是你应该有意依赖的东西. (2认同)

Dan*_*olt 8

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

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

我知道的唯一解决方案是创建一个系统范围的钩子,查找指示窗口的消息被破坏(WM_CLOSE,WM_DESTROY).然后,您将比较消息窗口句柄与您持有的句柄,以查看您关心的任何窗口是否受到影响.有关系统范围挂钩的更多信息,请参见此处.