[英]Win32 API - HWND “{unused = ???} Unable to read memory” error
[英]Validate HWND using Win32 API
从使用C ++的本机Win32 API可以确定与HWND关联的窗口是否仍然有效?
您可以使用Win32 API IsWindow 。
不建议使用它,原因有两个:
从MSDN(与上面相同的链接):
线程不应该将IsWindow用于它没有创建的窗口,因为在调用此函数后窗口可能会被销毁。 此外,由于窗口把手被回收,手柄甚至可以指向不同的窗口。
可以做些什么?
也许您的问题可以重新设计,这样您就不需要检查有效的句柄。 例如,您可以建立从客户端到服务器的管道。
您还可以创建一个Windows挂钩来检测何时发生某些消息,但这对于大多数需求来说可能是过度的。
这个问题已经过时了,但我自己需要这个功能,在阅读了有关警告之后有点失望。 然而,在做了一点挖掘后,似乎一切都很顺利。 除非你正在处理16位程序,否则IsWindow似乎是要走的路。 手柄重复使用的问题似乎已经充分解决了这个问题:
http://blogs.msdn.com/b/oldnewthing/archive/2007/07/17/3903614.aspx
因此,由于高16位重用计数器,您不太可能遇到窗口重用问题。
您可以使用IsWindow()或尝试使用SendMessage (hWnd,WM_NULL)向窗口发送WM_NULL消息,并查看它是否成功。
此外,如果窗口不在您的控制范围内,则可以随时销毁窗口。 正如其他人所说,当句柄被重用时,句柄可能属于另一个窗口。 实际上我不知道这有多大可能性。
我知道的唯一解决方案是创建一个系统范围的钩子 ,查找指示窗口的消息被破坏(WM_CLOSE,WM_DESTROY)。 然后,您将比较消息窗口句柄与您持有的句柄,以查看您关心的任何窗口是否受到影响。 有关系统范围挂钩的更多信息,请参见此处。
如果有问题的窗口的窗口过程在您的控制之下(或者您可以将其子类化),那么我建议注册窗口响应的自定义消息,其结果为非零。 将该消息发送到任何其他窗口(或无效的HWND)将导致0。
当然,这只会告诉您HWND是否指向您控制的其中一个窗口 - 但可能会给出上面的其他答案甚至可能是有利的。
使用RegisterWindowMessage使用足够唯一的名称注册消息。
也许IsWindow
, FindWindow
和GetWindowThreadProcessId
的组合会更准确
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(IsWindow(FindWindow(NULL , TEXT("Example Window Name")))){
// do stuff
}
将检查窗口是否存在并具有适当的名称
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.