简体   繁体   English

使用CreateWindow创建win32模式窗口

[英]Creating a win32 modal window with CreateWindow

I create a window with CreateWindow() and show it with ShowWindow() . 我使用CreateWindow()创建一个窗口并使用ShowWindow()显示它。 But the parent window on which this was created should be disabled until user returns from this window, ie it should simulate modal dialog box. 但是应该禁用创建它的父窗口,直到用户从该窗口返回,即它应该模拟模式对话框。

Make sure you set the hwndParent in CreateWindow and use EnableWindow(hwndParent, FALSE) to disable the parent after showing the pop up window. 确保在CreateWindow设置hwndParent并使用EnableWindow(hwndParent, FALSE)在显示弹出窗口后禁用父级。 Then enable the parent with EnableWindow(hwndParent, TRUE) after the pop up window has been closed. 然后在弹出窗口关闭后启用具有EnableWindow(hwndParent, TRUE)的父级。

模态,第1部分:UI模态与代码模态解释了如何执行此操作,以及您可能不想要的原因。

You need to consider what it means to be a modal window - basically, the window's parent is disabled. 您需要考虑成为模态窗口意味着什么 - 基本上,窗口的父窗口被禁用。 The only automatic way of doing this (that I am aware of) is to call DialogBox() to create a modal dialog box. 这样做的唯一自动方式(我知道)是调用DialogBox()来创建一个模态对话框。 However, since you want to use CreateWindow() , then all that you need to do is to manually disable the parent window yourself. 但是,由于您要使用CreateWindow() ,因此您需要做的就是自己手动禁用父窗口。

Ideally, it would be better to go the dialog box route (since the OS knows exactly what must be done in order to create a modal window), but I suppose this option is there if you must use it. 理想情况下,最好去对话框路径(因为操作系统确切知道必须要做什么才能创建模态窗口),但我想如果你必须使用它,那么这个选项就在那里。

您还可以运行“辅助消息循环”,使父窗口保持非活动状态,直到您完成“模态”对话框的工作。

Okay I just wrestled with this same problem myself. 好吧,我自己也在解决同样的问题。 I needed a quick dialog that behaved like it would if I used DialogBox() but I didn't want to create a template for the particular project I was using. 我需要一个快速的对话框,其表现就像我使用DialogBox()时那样,但我不想为我正在使用的特定项目创建模板。

What I discovered is that if you disable the parent window of the dialog you also disable the dialog. 我发现如果您禁用对话框的父窗口,您也会禁用该对话框。 And you can't enable that dialog without re-enabling the parent dialog. 如果不重新启用父对话框,则无法启用该对话框。 So that method won't work. 所以这种方法不起作用。

I also discovered that you can't use SetCapture() / ReleaseCapture() because then the child windows of the dialog won't get messages. 我还发现你不能使用SetCapture()/ ReleaseCapture(),因为那时对话框的子窗口不会得到消息。

I did find a solution that works: Use a local message pump, driven by either PeekMessage() or GetMessage(). 我找到了一个有效的解决方案:使用本地消息泵,由PeekMessage()或GetMessage()驱动。 Here is the code that worked for me: 这是适合我的代码:

  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);
        }
     }
  }

What this effectively does is "eat" any mouse messages that are outside the client area of the window for all messages delivered to that application. 这实际上做的是“吃掉”窗口客户区域之外的任何鼠标消息,用于传递给该应用程序的所有消息。 It does not prohibit clicking outside the application, just clicking anywhere inside the application that isn't within the client area of the "modal" window. 它不禁止在应用程序外部单击,只需单击应用程序内不在“模态”窗口的客户区域内的任何位置。 If you add a MessageBeep() when you eat a message you'll get the exact same behavior as a real modal dialog. 如果您在吃消息时添加MessageBeep(),您将获得与真实模态对话框完全相同的行为。

m_bFinished is a BOOL member of the class and it gets set if either the OK or Cancel buttons are accessed on the "dialog," and under certain other conditions that are outside the scope of the code snippet here. m_bFinished是类的BOOL成员,如果在“对话框”上访问“确定”或“取消”按钮,并且在此处的代码片段范围之外的某些其他条件下,它将被设置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM