如何使用C++通过句柄关闭MessageBox窗口

3
我有一个多线程应用程序,可能会显示一个MessageBox供用户交互。消息框本身是在工作线程中显示的,在用户从应用程序系统托盘图标选择上下文菜单命令后显示,因此用户在消息框显示时可以继续使用应用程序。这很好用,直到用户发出“退出”命令为止,此时我需要找到一种方法来关闭任何打开的消息框。
我做了功课,并能够使用此方法(使用此方法)获取消息框的主要(对话框)窗口的HWND句柄。我使用Spy++检查了HWND是否正确,所以HWND本身不是问题所在。问题在于,当我从另一个线程向消息框发送PostMessage(hMsgBoxWnd, WM_CLOSE, 0, 0);时,它简单地忽略此消息并不关闭。
有没有办法根据其窗口句柄关闭消息框?

我认为通过显示类似于消息框的对话框来处理这个问题会更容易,这样你就知道要发送什么消息来关闭它。 - Jerry Coffin
这很奇怪,因为我发誓之前在某个地方使用了完全相同的技术,而且它完美地运行。 - chris
@JerryCoffin:是的,这样做确实可以解决问题,但也需要我重新编写很多代码。我会先尝试找到解决方案... - c00000fd
1
我不知道为什么 WM_CLOSE 不起作用,但你也可以尝试发送一个 WM_COMMAND 消息来模拟单击其中一个按钮(例如 PostMessage(hMsgBoxWnd, WM_COMMAND, MAKEWPARAM(IDCANCEL, BN_CLICKED), 0);)。 - Jonathan Potter
@JonathanPotter:似乎MessageBox API仍然使用主线程消息泵,即使我从工作线程调用它,这似乎是WM_CLOSE被拖延的原因... - c00000fd
@user843732:MessageBox() 使用调用它的线程的消息队列。在内部,MessageBox() 运行自己的消息循环,因为它是一个模态对话框。在某些情况下,MessageBox() 简单地不响应 WM_CLOSE:http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/18be2271-d7ec-4fee-9960-e90a4cb91758 - Remy Lebeau
2个回答

1

0

你应该使用PostThreadMessage来向特定线程的消息队列发送消息


你说的有道理,但在我的情况下PostThreadMessage不起作用,因为那个工作线程没有消息泵... - c00000fd
@user843732,你可以添加一个快速的PeekMessage循环,以便不会对该线程的其他组件产生很大干扰。 - chris
@chris:你看,问题就在于(就像我之前发布的那样),MessageBox 显然仍然使用主线程来获取其消息。我知道这个原因是因为当我将 NULL 指定为其第一个参数时,我的关闭方法开始工作了。这里的问题是 MessageBox 然后在任务栏上创建了自己的按钮,而我不想要它... - c00000fd
@user843732,我甚至觉得说这话很糟糕,但如果那是唯一的问题,你可以在创建消息框后使用SetWindowLongPtr将其扩展样式更改为WS_EX_TOOLWINDOW。在必须这样做之前,这应该可以作为一个hackish的最后手段。 - chris
另一个选项是使用SetWindowsHookEx拦截Windows消息框消息,或制作自动关闭的消息框。本文讨论如何自定义标准消息框:http://www.catch22.net/tuts/custom-messagebox - stamhaney
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接