2014-11-05 152 views
2

有没有一种简单的方式来无模式显示对话框,同时保留UI阻止模式对话框提供?如何在无模式对话框中模拟模态对话框UI行为?

我想在显示对话框时停止用户与其他对话框/控件的交互,但让应用程序继续运行。有没有办法将对话框设置为“独占焦点”或类似的东西? (应用程序主窗口)

+0

你用'EnableWindow(mainWnd,FALSE)'然后'CreateDialog(mainWnd,...)'尝试过吗? – rodrigo 2014-11-05 08:57:10

+0

我在MFC工作,但我认为你的问题转移 - 但我不知道从对话框启动的地方获得'mainWnd'是多么容易。尽管根据这个提交答案。 – 2014-11-05 09:07:22

+0

那么,你需要拥有者窗口来创建对话框。或者如果你使用默认的主窗口,只需使用'AfxGetMainWnd()'。我没有作为回答发布,因为我不知道它是否会工作或看起来很奇怪,只是一个想法... – rodrigo 2014-11-05 09:15:43

回答

2

不,没有简单的方法去做你想做的事。

如果你真的想走你描述的路线,我建议先阅读Raymond Chen的博客上的整个'模态'系列。第一批在http://blogs.msdn.com/b/oldnewthing/archive/2005/02/18/376080.aspx

但是,这似乎是XY问题的一个实例。你试图做什么?获取主应用程序以不断更新自身?如果是这样,我认为(用我们提供的信息)调用AfxPumpMessage()将做你想做的。或者你想继续处理主应用程序中的数据?然后你可以通过使用工作者线程为自己节省一个伤害的世界。

1

未经检验的,但你可以尝试做禁用所有者窗口,创建一个无模式对话框,然后在对话框关闭,重新启用它:

要禁用主窗口:

AfxGetMainWnd()->EnableWindow(FALSE); 

要创建模式/非阻塞对话框:

dlg->Create(resId) 

并再次启用它,在OnClose事件,或类似:

AfxGetMainWnd()->EnableWindow(TRUE); 

在我不知道的模式对话框中可能有其他细节。如果您愿意调查,请阅读MFC的CDialog::DoModal()的源代码。如果我没有记错的话,这个MFC函数使用无模Win32 API CreateDialog*()来模拟一个模态阻塞对话框,以实现全局加速器,钩子,消息等等。

+0

我认为这基本上是_is_同样的解决方案陈在博客Roel提供的链接(Old New Thing,Modality Part 1)中提供。 – 2014-11-06 09:03:11

-1

这里可以回答你的问题:

您可以禁用应用程序中的所有其他控件,然后在对话框完成后重新启用它们。

使用此回调

BOOL CALLBACK EnableDisableAllChildren (HWND hwnd, LPARAM lp) 
{ 
    ::EnableWindow (hwnd, (BOOL)lp); 

    return TRUE; 
} 

通过调用

EnumChildWindows (HWNDToYourApp, EnableDisableAllChildren, true); 

待办事项Modaless对话框

EnumChildWindows (HWNDToYourApp, EnableDisableAllChildren, false); 

不同的东西来思考。

+0

当对话框管理器关闭对话框时,它将输入焦点传送到适当的窗口。潜在的候选人必须启用。由于应用程序的所有子窗口在对话框关闭时仍然处于禁用状态,因此您只需吹走最后一次重新获得输入焦点的机会。此应用程序不会公开可用的键盘接口。 – IInspectable 2014-11-06 19:17:51

+0

@IInspectable他可以在对话框本身的禁用和启用 – 2014-11-07 00:41:27

+0

我对发布的解决方案发表评论。如果它附带一个免责声明,“*必须修正以使其可行”*,则它不能成为解决方案。虽然这个缺陷可以解决,但它不是唯一的:在对话框关闭时无条件地启用所有子窗口也将启用最初禁用的窗口,或者由于用户与对话的交互而被禁用的窗口。解决方案变成了一个难题。 – IInspectable 2014-11-07 10:45:15