使用EnableWindow()函数时,Winapi:窗口被“发送回”

时间:2013-08-12 09:11:19

标签: winapi focus messagebox

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

EnableWindow(main_window,FALSE);

我有一个示例MessageBox:

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

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

SetFocus(main_window);
SetActiveWindow(main_window);

之前和之后:EnableWindow(main_window,TRUE)结果很奇怪:它工作50/50。我猜我是这样做的。

顺便说一下。 BLOCK鼠标点击特定窗口是否有更好的解决方案:

EnableWindow(main_window,FALSE);

1 个答案:

答案 0 :(得分:4)

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

除此之外,它不是。

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

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

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

(*):遗憾的是,CreateDialog的形式参数错误地命名为hWndParent亲子所有者拥有的关系非常不同(请参阅About Windows)。