windows 处理无效的窗口句柄
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3386845/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Handling invalid window handle
提问by Luca
The application retrieve window handles, using Enum* routines.
应用程序使用 Enum* 例程检索窗口句柄。
It happens that in the while the application manage the handle (get class name, window statistics...) of an enumerated/created window, the handle is no more valid. The code managing window handles are protected using a try/catch block, but the window handle is stored and the successively used for managing the represented window.
碰巧在应用程序管理枚举/创建窗口的句柄(获取类名、窗口统计信息...)时,句柄不再有效。使用 try/catch 块保护管理窗口句柄的代码,但存储窗口句柄并连续用于管理表示的窗口。
How to handle the window handle lifetime? It is possible to detect the handle invalidity?
如何处理窗口句柄生命周期?是否可以检测句柄无效?
I'd like to avoid try/catch blocks every time the application uses the window handles.
每次应用程序使用窗口句柄时,我都想避免 try/catch 块。
采纳答案by Luca
I already have the actual solution... but I didn't know about this until now!
我已经有了实际的解决方案……但直到现在我才知道!
Thank you all for having clarified about the window handle lifetime, but there is actually a method for being detected about window handle lifetime: CbtProc.
感谢大家对窗口句柄生存期的澄清,但实际上有一种检测窗口句柄生存期的方法:CbtProc。
In the case the hook is installed system wide, it's possible to notify specific applications (it depends all on real implementation of the CBT hook) about a window destroy, which indicates that the a specific handle won't be valid after the notification.
在钩子安装在系统范围内的情况下,可以通知特定应用程序(这完全取决于 CBT 钩子的实际实现)关于窗口销毁,这表明特定句柄在通知后将无效。
From the documentation:
从文档:
HCBT_DESTROYWND Specifies the handle to the window about to be destroyed.
HCBT_DESTROYWND 指定即将被销毁的窗口的句柄。
Of course the access of the handles using WINAPI routines must be synchronized with the notification system, which doesn't seem to give good feasibility (CBT hook actually blocks window destroy because it is synchronized with the application logic).
当然,使用 WINAPI 例程的句柄访问必须与通知系统同步,这似乎没有给出很好的可行性(CBT 钩子实际上阻止了窗口销毁,因为它与应用程序逻辑同步)。
回答by Chris Becke
Window handles are only safe if used from the thread that created the window. From any other thread, all you can know about a window handle is, it was valid sometime in the past. right now, it may or may not be, and if it is, it could refer to a different window than intended entirely.
窗口句柄只有在创建窗口的线程中使用时才是安全的。从任何其他线程中,您所知道的关于窗口句柄的所有信息是,它在过去的某个时间是有效的。现在,它可能是也可能不是,如果是,它可能指的是与预期完全不同的窗口。
回答by Alex K.
You can pass it to IsWindow()
to validate it.
There are a couple of caveats, however both will apply to pretty much any approach to this:
您可以将其传递IsWindow()
给以验证它。
有几个警告,但是两者都适用于几乎任何方法:
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.
线程不应将 IsWindow 用于它未创建的窗口,因为在调用此函数后该窗口可能会被销毁。此外,因为窗口句柄被回收,句柄甚至可以指向不同的窗口。
If your doing this to a window in one of your own external apps, you could add a 2nd tier of validation by Set/GetProp()'ing a unique identifier of some kind.
如果您在自己的外部应用程序之一中对窗口执行此操作,则可以通过 Set/GetProp() 使用某种唯一标识符来添加第二层验证。
回答by onof
You can use the GetWindowInfo
function. It returns 0 if the handle is not valid.
您可以使用该GetWindowInfo
功能。如果句柄无效,则返回 0。