我创建了一个CreateWindow()
的窗口,并显示ShowWindow()
。但是应该禁用创建它的父窗口,直到用户从该窗口返回,即它应该模拟模式对话框。
答案 0 :(得分:18)
确保在hwndParent
中设置CreateWindow
并在显示弹出窗口后使用EnableWindow(hwndParent, FALSE)
禁用父级。然后在弹出窗口关闭后,使用EnableWindow(hwndParent, TRUE)
启用父级。
答案 1 :(得分:13)
Modality, part 1: UI-modality vs code-modality解释了如何执行此操作以及您可能不想这样做的原因。
答案 2 :(得分:3)
您需要考虑成为模态窗口意味着什么 - 基本上,窗口的父窗口被禁用。这样做的唯一自动方式(我知道)是调用DialogBox()
来创建模态对话框。但是,由于您要使用CreateWindow()
,因此您需要做的就是自己手动禁用父窗口。
理想情况下,最好去对话框路径(因为操作系统确切知道必须要做什么才能创建模态窗口),但我想如果你必须使用它,那么这个选项就在那里。
答案 3 :(得分:2)
您还可以运行“辅助消息循环”,使父窗口保持非活动状态,直到您完成“模态”对话框的工作。
答案 4 :(得分:0)
好吧,我自己也在努力解决同样的问题。我需要一个快速的对话框,其表现就像我使用DialogBox()时那样,但我不想为我正在使用的特定项目创建模板。
我发现如果您禁用对话框的父窗口,您也会禁用该对话框。并且您无法在不重新启用父对话框的情况下启用该对话框。所以这种方法不起作用。
我还发现你不能使用SetCapture()/ ReleaseCapture(),因为那时对话框的子窗口不会收到消息。
我找到了一个有效的解决方案:使用本地消息泵,由PeekMessage()或GetMessage()驱动。以下代码对我有用:
while (!m_bFinished)
{
BOOL bEat;
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_CHAR)
{
if (msg.wParam == VK_ESCAPE)
{
m_bFinished = TRUE;
continue;
}
}
bEat = FALSE;
if (msg.message >= WM_MOUSEFIRST &&
msg.message <= WM_MOUSELAST)
{
RECT rectMe;
pcMe->GetWindowRect(&rectMe);
if (!::PtInRect(&rectMe, msg.pt))
bEat = TRUE;
}
if (!bEat)
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
}
这实际上做的是&#34;吃&#34;传递给该应用程序的所有消息的窗口客户区外的任何鼠标消息。它不禁止在应用程序外单击,只需单击应用程序内任何位于&#34;模式&#34;的客户区域内的任何位置。窗口。如果您在吃消息时添加MessageBeep(),您将获得与真实模态对话框完全相同的行为。
m_bFinished是该类的BOOL成员,如果在&#34;对话框中访问“确定”或“取消”按钮,它将被设置为&#34;并且在此处的代码段范围之外的某些其他条件下。