C++ 使用 CreateWindow 创建一个 win32 模态窗口
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/734674/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Creating a win32 modal window with CreateWindow
提问by cagribal
I create a window with CreateWindow()
and show it with ShowWindow()
. But the parent window on which this was created should be disabled until user returns from this window, i.e. it should simulate modal dialog box.
我创建了一个窗口CreateWindow()
并用ShowWindow()
. 但是创建它的父窗口应该被禁用,直到用户从这个窗口返回,即它应该模拟模态对话框。
回答by Maurice Flanagan
Make sure you set the hwndParent
in CreateWindow
and use EnableWindow(hwndParent, FALSE)
to disable the parent after showing the pop up window. Then enable the parent with EnableWindow(hwndParent, TRUE)
after the pop up window has been closed.
确保在显示弹出窗口后设置hwndParent
inCreateWindow
和 useEnableWindow(hwndParent, FALSE)
以禁用父级。然后EnableWindow(hwndParent, TRUE)
在弹出窗口关闭后启用父级。
回答by jeffm
Modality, part 1: UI-modality vs code-modalityexplains how to do this, and why you might not want to.
模态,第 1 部分:UI 模态与代码模态解释了如何执行此操作,以及您可能不想这样做的原因。
回答by Andy
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. However, since you want to use CreateWindow()
, then all that you need to do is to manually disable the parent window yourself.
您需要考虑成为模态窗口意味着什么 - 基本上,窗口的父窗口被禁用。执行此操作的唯一自动方法(我知道)是调用DialogBox()
以创建模态对话框。但是,既然您想使用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.
理想情况下,最好走对话框路线(因为操作系统确切地知道为了创建模态窗口必须做什么),但我想如果您必须使用它,则可以使用此选项。
回答by Agnel Kurian
You could also run a "secondary message loop" which keeps the parent window inactive till your work with the "modal" dialog is finished.
您还可以运行“辅助消息循环”,使父窗口保持非活动状态,直到您对“模态”对话框的工作完成。
回答by Gixxernaut
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(). Here is the code that worked for me:
我确实找到了一个有效的解决方案:使用由 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);
}
}
}
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 成员,如果在“对话框”上访问 OK 或 Cancel 按钮,以及在此处代码片段范围之外的某些其他条件下,它就会被设置。