Хорошо, я сам боролся с этой же проблемой. Мне нужен был быстрый диалог, который бы вел себя так, как если бы я использовал 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);
}
}
}
Что это эффективно делает, так это «съедает» любые сообщения мыши, которые находятся за пределами клиентской области окна, для всех сообщений, доставляемых в это приложение. Он не запрещает щелкать вне приложения, просто щелкая в любом месте внутри приложения, которое не находится в клиентской области «модального» окна. Если вы добавите MessageBeep () при получении сообщения, вы получите то же поведение, что и в реальном модальном диалоге.
m_bFinished является членом BOOL класса и устанавливается, если в диалоговом окне доступны кнопки «ОК» или «Отмена», а также при определенных других условиях, выходящих за рамки фрагмента кода.