有没有一种简单的方式来无模式显示对话框,同时保留UI阻止模式对话框提供?如何在无模式对话框中模拟模态对话框UI行为?
我想在显示对话框时停止用户与其他对话框/控件的交互,但让应用程序继续运行。有没有办法将对话框设置为“独占焦点”或类似的东西? (应用程序主窗口)
有没有一种简单的方式来无模式显示对话框,同时保留UI阻止模式对话框提供?如何在无模式对话框中模拟模态对话框UI行为?
我想在显示对话框时停止用户与其他对话框/控件的交互,但让应用程序继续运行。有没有办法将对话框设置为“独占焦点”或类似的东西? (应用程序主窗口)
不,没有简单的方法去做你想做的事。
如果你真的想走你描述的路线,我建议先阅读Raymond Chen的博客上的整个'模态'系列。第一批在http://blogs.msdn.com/b/oldnewthing/archive/2005/02/18/376080.aspx。
但是,这似乎是XY问题的一个实例。你试图做什么?获取主应用程序以不断更新自身?如果是这样,我认为(用我们提供的信息)调用AfxPumpMessage()将做你想做的。或者你想继续处理主应用程序中的数据?然后你可以通过使用工作者线程为自己节省一个伤害的世界。
未经检验的,但你可以尝试做禁用所有者窗口,创建一个无模式对话框,然后在对话框关闭,重新启用它:
要禁用主窗口:
AfxGetMainWnd()->EnableWindow(FALSE);
要创建模式/非阻塞对话框:
dlg->Create(resId)
并再次启用它,在OnClose事件,或类似:
AfxGetMainWnd()->EnableWindow(TRUE);
在我不知道的模式对话框中可能有其他细节。如果您愿意调查,请阅读MFC的CDialog::DoModal()
的源代码。如果我没有记错的话,这个MFC函数使用无模Win32 API CreateDialog*()
来模拟一个模态阻塞对话框,以实现全局加速器,钩子,消息等等。
我认为这基本上是_is_同样的解决方案陈在博客Roel提供的链接(Old New Thing,Modality Part 1)中提供。 – 2014-11-06 09:03:11
这里可以回答你的问题:
您可以禁用应用程序中的所有其他控件,然后在对话框完成后重新启用它们。
使用此回调
BOOL CALLBACK EnableDisableAllChildren (HWND hwnd, LPARAM lp)
{
::EnableWindow (hwnd, (BOOL)lp);
return TRUE;
}
通过调用
EnumChildWindows (HWNDToYourApp, EnableDisableAllChildren, true);
待办事项Modaless对话框
EnumChildWindows (HWNDToYourApp, EnableDisableAllChildren, false);
不同的东西来思考。
当对话框管理器关闭对话框时,它将输入焦点传送到适当的窗口。潜在的候选人必须启用。由于应用程序的所有子窗口在对话框关闭时仍然处于禁用状态,因此您只需吹走最后一次重新获得输入焦点的机会。此应用程序不会公开可用的键盘接口。 – IInspectable 2014-11-06 19:17:51
@IInspectable他可以在对话框本身的禁用和启用 – 2014-11-07 00:41:27
我对发布的解决方案发表评论。如果它附带一个免责声明,“*必须修正以使其可行”*,则它不能成为解决方案。虽然这个缺陷可以解决,但它不是唯一的:在对话框关闭时无条件地启用所有子窗口也将启用最初禁用的窗口,或者由于用户与对话的交互而被禁用的窗口。解决方案变成了一个难题。 – IInspectable 2014-11-07 10:45:15
你用'EnableWindow(mainWnd,FALSE)'然后'CreateDialog(mainWnd,...)'尝试过吗? – rodrigo 2014-11-05 08:57:10
我在MFC工作,但我认为你的问题转移 - 但我不知道从对话框启动的地方获得'mainWnd'是多么容易。尽管根据这个提交答案。 – 2014-11-05 09:07:22
那么,你需要拥有者窗口来创建对话框。或者如果你使用默认的主窗口,只需使用'AfxGetMainWnd()'。我没有作为回答发布,因为我不知道它是否会工作或看起来很奇怪,只是一个想法... – rodrigo 2014-11-05 09:15:43