2

应用程序使用 Enum* 例程检索窗口句柄。

碰巧在应用程序管理枚举/创建窗口的句柄(获取类名,窗口统计信息......)时,句柄不再有效。管理窗口句柄的代码使用 try/catch 块进行保护,但窗口句柄被存储并随后用于管理所表示的窗口。

如何处理窗口句柄生命周期?是否可以检测到句柄无效?

每次应用程序使用窗口句柄时,我都想避免 try/catch 块。

4

4 回答 4

2

窗口句柄只有在创建窗口的线程中使用时才是安全的。从任何其他线程中,您所能知道的关于窗口句柄的所有信息都是,它在过去的某个时间是有效的。现在,它可能是也可能不是,如果是,它可能指的是与完全预期不同的窗口。

于 2010-08-02T18:58:46.960 回答
2

我已经有了实际的解决方案……但直到现在我才知道!

感谢大家对窗口句柄生命周期的澄清,但实际上有一种检测窗口句柄生命周期的方法:CbtProc

如果钩子安装在系统范围内,则可以通知特定应用程序(这完全取决于 CBT 钩子的实际实现)有关窗口销毁,这表明特定句柄在通知后将无效。

从文档中:

HCBT_DESTROYWND 指定要销毁的窗口的句柄。

当然,使用 WINAPI 例程访问句柄必须与通知系统同步,这似乎没有很好的可行性(CBT 挂钩实际上阻止了窗口销毁,因为它与应用程序逻辑同步)。

于 2010-08-03T16:33:12.047 回答
1

您可以将其传递给以IsWindow()进行验证。
有一些警告,但是两者都适用于几乎任何方法:

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

如果您对自己的外部应用程序中的一个窗口执行此操作,则可以通过 Set/GetProp()'ing 某种唯一标识符添加第二层验证。

于 2010-08-02T11:01:23.023 回答
0

您可以使用该GetWindowInfo功能。如果句柄无效,则返回 0。

于 2010-08-02T10:42:53.993 回答