【问题标题】:Close window that ignores WM_CLOSE?关闭忽略 WM_CLOSE 的窗口?
【发布时间】:2016-11-21 01:21:43
【问题描述】:

我想从我的应用程序中关闭一些应用程序的窗口。我尝试将WM_CLOSE 消息发送到该窗口(它对某些窗口非常有效),但有些窗口忽略了WM_CLOSE。然后我发现this 文章说如果我想关闭窗口,我可以调用DestroyWindow WINAPI 函数。但是,根据documentation,“一个线程不能使用DestroyWindow 来破坏由另一个线程创建的窗口”。所以我不能从我的应用程序中使用它来关闭另一个应用程序的窗口。

所以我的问题是 - 是否可以关闭忽略 WM_CLOSE 消息的应用程序窗口?我确实想完全关闭窗口(例如弹出窗口),不退出应用程序,不关闭与该窗口相关的线程等等。

编辑: 我肯定知道,那个窗口故意忽略了我的WM_CLOSE,因为我通过 spy++ 看到它收到了我的WM_CLOSE 消息。而且我不想实现“点击右上角[X]按钮”,因为我想要统一的解决方案(我有问题的窗口根本没有按钮[X])。

【问题讨论】:

    标签: c# windows winapi


    【解决方案1】:

    WM_CLOSE 是关闭遵循标准规则的窗口的标准方法。显然您的目标窗口没有,因此标准解决方案将不起作用。

    不过,还有一个可能的替代方案。正如您已经发现的那样,只有拥有该窗口的线程才能销毁该窗口。所以你必须让所有者线程销毁窗口。您可以使用GetWindowThreadProcessId() 获取目标窗口的所属线程ID,然后使用SetWindowsHookEx() 将线程特定的消息挂钩安装到该线程中(挂钩回调必须在DLL 中实现),最后发送自定义窗口消息到目标窗口。当消息钩子接收到消息时,它将运行在窗口所属线程的上下文中,从而可以销毁窗口。

    【讨论】:

      【解决方案2】:

      窗口忽略您的 WM_CLOSE 有几个原因:

      1. 窗口可能故意忽略WM_CLOSE,因为它自己的逻辑认为窗口不能关闭。 (例如,它仍在等待用户在所有编辑字段中输入文本)。如果您强制关闭窗口,您可能会导致应用程序本身出现未定义的行为。

      2. 您没有说明您是如何获得有问题的窗口句柄 (HWND)。这可能值得研究,因为您的代码可能有错误。

      作为最后的手段,您始终可以实现将鼠标光标移动到窗口右上角并模拟鼠标单击[X] 关闭按钮顶部的代码。或单击窗口将其置于前台并通过SendInput 注入ALT+F4 击键

      【讨论】:

      • 抱歉,不小心按了 Enter。 1. 我肯定知道,那个窗口故意忽略了我的WM_CLOSE,因为我通过 spy++ 看到它收到了我的WM_CLOSE 消息。这个窗口右上角没有[X]关闭按钮,这个窗口有自己的“关闭”按钮(不在右上角)。但我想要统一的解决方案,它适用于所有可能的窗口。 2.我通过SetWinEventHook函数获取窗口句柄(寻找EVENT_OBJECT_CREATE事件)。而且我可以验证句柄是否正确,因为我还使用 spy++ 进行了检查
      • 没错,它是一个自定义窗口,并且有自己的逻辑来确定如何销毁自己。在这种情况下,这很简单。您需要模拟用户单击该按钮。
      • 投反对票的人愿意解释他不喜欢什么吗?
      • @KtulhuGreen 一个适用于“所有可能的窗口”的解决方案是不可能的。
      • @selbie:因为您提出的解决方案不适用于具有带有照明符号而不是关闭按钮的自定义绘制框架的虚构应用程序,所以单击此破坏宇宙不会关闭应用程序。现在认真:如果我记得正确单击关闭按钮和/或按 ALT+F4 发送 WM_CLOSE 消息,那么您提出的解决方案是“您必须发送 WM_CLOSE 而不是发送 WM_CLOSE。”
      猜你喜欢
      • 2023-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-15
      • 1970-01-01
      相关资源
      最近更新 更多