1

在使用 MessageDlg 并尝试通过Taskbar close all/group 命令关闭我的应用程序时,我注意到了一个奇怪的行为。

我的申请如下:

  1. 有一个隐藏的主窗体除了处理一些 Windows 消息并将它们传递到子窗口(如有必要)之外什么都不做。
  2. 每个子窗口都将其父窗口设置为桌面(以使其显示在任务栏上)。
  3. 每个孩子都有一个 OnClose 事件,它会弹出一个 MessageDlg 来提示用户是否要保存他们的会话(如果有任何内容已被修改)

问题似乎是它会不断关闭任何未修改的窗口,但是,当它碰到一个已经被修改的窗口时,两件事中的一件会间歇性地发生:

  1. 无论我是否选择“是/否”,关闭所有进程似乎都会在该特定窗口关闭后停止。
  2. 对话框不显示,结果是 mrCancel。关闭此窗口后,关闭所有进程再次停止。

我所做的更改是使用 WinAPI MessageBox函数代替 MessageDlg,这似乎确实解决了这个问题。但是,我真的很想知道为什么 MessageDlg 会这样?

我最初的想法是当对话框在 Close All 中间启动时,操作系统可能正在向对话框发送 WM_CLOSE 消息,因为它在技术上是该组的一部分(这可以解释对话框没有出现并且默认为 mrCancel,因为这个相当于按 X)。但是,这并不能解释为什么在我关闭对话框后,关闭所有进程不会继续关闭组中的任何其他窗口!

对此有什么想法/想法吗?

4

2 回答 2

3

Windows 不会WM_CLOSE向这些窗口发送消息,它会WM_SYSCOMMANDSC_CLOSE请求一起发布。WM_CLOSE如果使用标准 Windows 消息框,这又会导致发送消息。如果MessageDlg()改为使用该函数,则只有第一个发布WM_SYSCOMMAND导致 a WM_CLOSE,其他则不会。很难确定,但这可能与VCL 用来“伪造”模态对话框的DisableTaskWindows()and调用有关。EnableTaskWindows()如果将 Windows 函数替换为Application.MessageBox()确实使用DisableTaskWindows()and的包装器EnableTaskWindows(),那么它也不起作用(IMO 支持这种推理)。

于 2009-12-10T22:08:32.780 回答
0

我想我可以解释为什么从 切换MessageDlgMessageBox让事情变得不同。MessageDlg反过来调用MessageDlgPosHelp创建一个看起来像 Windows 的 Delphi 窗体MessageBox,这个窗体被称为显示ShowModal。这会锁定整个应用程序,直到它关闭。

MessageBox,另一方面,默认情况下,MB_APPLMODAL这意味着您必须先将其关闭,然后才能使用它所附加的窗口。如果您在 uFlags 参数中没有指定任何内容,则这是默认设置。这只会阻止您返回hwnd参数中指定的窗口,因此您的应用程序中的其他窗口仍然可以访问。

于 2009-12-10T15:42:13.763 回答