使用CreateWindow创建win32模式窗口

时间:2009-04-09 15:13:44

标签: c++ windows winapi modal-dialog

我创建了一个CreateWindow()的窗口,并显示ShowWindow()。但是应该禁用创建它的父窗口,直到用户从该窗口返回,即它应该模拟模式对话框。

5 个答案:

答案 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;并且在此处的代码段范围之外的某些其他条件下。