3

为了防止用户在出现 MessageBox 时单击我的 main_window,我使用了:

EnableWindow(main_window,FALSE);

我有一个示例消息框:

EnableWindow(main_window,FALSE); 
MessageBox(NULL,"some text here","About me",MB_ICONASTERISK);
EnableWindow(main_window,TRUE);

问题是,当我在 MessageBox 上按“确定”时,它会关闭,并且我的 main_window 被发送到所有其他系统窗口的后面。为什么会这样?我试着说:

SetFocus(main_window);
SetActiveWindow(main_window);

之后和之前:EnableWindow(main_window,TRUE) 结果很奇怪:它的工作率为 50/50。我猜我是按不应该的方式做的。

顺便提一句。是否有比阻止鼠标单击特定窗口更好的解决方案:

EnableWindow(main_window,FALSE);
4

1 回答 1

4

显示模态 UI 需要启用模态子项并禁用所有者。当模态孩子完成时,必须反转过程。您发布的代码看起来像是实现这一点的直接方式。

除了,它不是。

问题出在调用MessageBox和之间EnableWindow,代码不是您编写的。MessageBox在模态子项(消息框)被销毁后返回。由于这是具有前台激活的窗口,因此窗口管理器会尝试找到要激活的新窗口。没有拥有窗口,所以它从 Z 顺序的顶部开始搜索。它找到的第一个窗口是你的,但它仍然被禁用。所以窗口管理器跳过它并寻找另一个窗口,一个未被禁用的窗口。到EnableWindow执行调用时为时已晚 - 窗口管理器已经得出结论,应该激活另一个窗口。

正确的顺序是在销毁模态 UI 之前启用所有者。

但是,只有当您有理由自己实施模态时,才需要这样做。系统提供模态UI的标准实现。为了利用它,将拥有窗口的句柄传递给类似MessageBoxCreateDialog(*) 的调用,窗口管理器将为您完成所有繁重的工作。

(*):CreateDialog不幸的是,形式参数 to 被错误命名为hWndParent. 父子关系和所有者拥有的关系非常不同(请参阅关于 Windows)。

于 2013-08-12T10:37:02.090 回答