【问题标题】:Handling invalid window handle处理无效的窗口句柄
【发布时间】:2011-03-24 03:28:37
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: c# windows winapi window-handles


    【解决方案1】:

    您可以使用GetWindowInfo 函数。如果句柄无效,则返回 0。

    【讨论】:

    • -1 IsWindow 是您正在寻找的功能。此外,OP 需要通知句柄销毁,而不是验证句柄。
    【解决方案2】:

    您可以将其传递给IsWindow() 进行验证。
    有几个注意事项,但两者都适用于几乎任何解决此问题的方法:

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

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

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

        来自文档:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-09-07
          • 2014-08-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多