Winapi:使用 EnableWindow() 函数时窗口为 "sent to back"

标签 winapi focus messagebox

为了防止用户在出现 MessageBox 时点击我的主窗口,我使用了:

EnableWindow(main_window,FALSE);

我有一个示例 MessageBox:

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);

最佳答案

显示模态 UI 需要启用模态子项并禁用所有者。当模态 child 完成时,必须颠倒该过程。您发布的代码看起来是实现此目的的直接方法。

除了,它不是。

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

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

然而,只有当您有理由自己实现模态时,才有必要这样做。系统提供模态 UI 的标准实现。要使用它,请将句柄传递给所属窗口以调用 MessageBox。或 CreateDialog (*),窗口管理器将为您完成所有繁重的工作。

(*):很遗憾,CreateDialog 的形式参数被错误命名为 hWndParent亲子拥有 的关系非常不同(参见 About Windows )。

关于Winapi:使用 EnableWindow() 函数时窗口为 "sent to back",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18183289/

相关文章:

c++ - WinApi压缩,python3中的解压缩

c++ - 在对话框中以编程方式更改 Tab 键顺序的其他方法

c# - 弹出UAC消息时屏幕颜色默认为正常(无法检测到)

javascript - 如何滚动/聚焦到 contenteditable div 内的插入符号或元素?

android - 我的 PopupWindow 不断窃取 EditText 的焦点

javascript如何检查浏览器是否获得焦点

c# - 在 C# 中的 MessageBox 中显示当前日期时间

c - 在消息框中显示双倍

c++ - 如何获取显示设备的驱动版本?

c# - 在 MessageBoxManager 上设置超时