【问题标题】:::PostMessage to an invalid hWnd::PostMessage 到无效的 hWnd
【发布时间】:2013-06-13 20:08:32
【问题描述】:

我有一个线程调用::PostMessage(hWnd, [...]); 向主线程发送一条消息,提醒它异步操作的结果。

但是,我担心如果线程需要很长时间才能完成其操作,那么在调用PostMessagehWnd 可能不存在(用户可能已经关闭了窗口)。

如果hWnd 无效,MSDN Documentation 不会说明任何结果。

您是否从经验或其他文档中知道如果hWnd 无效,我可以期待什么?

【问题讨论】:

  • 也许你应该隐藏窗口而不是销毁它,直到线程完成使用它。
  • @Ben Voigt:我同意,但我在一家大型公司工作,无法控制这种架构选择。
  • 在大型公司环境中,您可以提交错误。看我的回答……著名的 Raymond Chen 说这是一个错误。另一种选择是使用weak_ptr 并在窗口被破坏时使其无效......尽管这会给您带来竞争条件,即从弱指针检索HWND 和实际调用PostMessage 之间的间隔。所以真的,你需要让窗口保持活力。
  • 另一种可能的解决方案是使用任何其他形式的跨线程队列。
  • 我通常做的是隐藏窗口并通知线程终止,(以任何方式工作:)。当线程即将终止时,它会向窗口发送最后一条自定义消息,指示窗口自行销毁。

标签: windows winapi


【解决方案1】:

Raymond Chen 写道:

一些选择摘录:

碰巧成船的程序(“boatloads”是一个技术术语)包含在窗口被破坏后使用窗口句柄的错误。当重新使用窗口句柄时,该程序会向它认为仍然存在的窗口发送一条消息,但它会将消息发送到一个完全不相关的窗口。这对程序来说不是好兆头,对于错误接收到消息的新窗口通常也不是一个好兆头。


我们上次结束了我们的故事,提出了程序向已经被破坏的窗口发送消息的问题,以及窗口句柄如何重用加剧了这个问题。虽然这显然是在销毁窗口后使用窗口句柄的程序中的一个错误,但这个问题非常普遍,以至于 Windows NT 中的窗口管理器人员决定采取更主动的方法。

【讨论】:

    【解决方案2】:

    正如其他人所指出的,Ramond Chen 解释了如果 HWND 被新窗口重新使用会发生什么。 PostMessage() 会成功,它只会进入错误的窗口。但是,如果 HWND 没有被重新使用,PostMessage() 将失败并出现 ERROR_INVALID_WINDOW_HANDLE (1400) 错误代码。

    【讨论】:

    • 不错的答案雷米。我有类似的担忧:如何在从不同线程向窗口发布消息之前确保窗口处于活动状态?即用户没有关闭窗口?我得到了与 OP 相同的问题,但我现在得到了明确的答案。
    • @amaninlove 在发布到它之前检查窗口是否有效是一种竞争条件。在线程完成发布到它之前不要破坏窗口。或者创建一个专用的message-only window 供帖子发布到。
    • 您有责任跟踪您的线程是否正在运行。只需在线程仍在运行时不要破坏窗口。当线程结束时,您可以销毁窗口。否则,当您要销毁窗口时,请先终止线程并等待它完全终止,然后才能真正销毁窗口
    • 那么我建议线程只发布到你可以完全控制它的生命周期的 HWND,这样你就可以确保它不会过早地被破坏。 message-only window 就是这样的 HWND
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-26
    • 1970-01-01
    • 1970-01-01
    • 2011-03-29
    • 1970-01-01
    相关资源
    最近更新 更多