,继续模态对话框创建前的线程将执行下面的代码。
让我们看看下面的对话框DoModal实现代码:
{
… …
// Disable 父窗口 (在创建对话框前)
HWND hWndParent = PreModal();
AfxUnhookWindowCreate();
BOOL bEnableParent = FALSE;
if (hWndParent != NULL && ::IsWindowEnabled(hWndParent))
{
::EnableWindow(hWndParent, FALSE);
bEnableParent = TRUE;
}
TRY
{
// 创建模态对话框
AfxHookWindowCreate(this);
if (CreateDlgIndirect(lpDialogTemplate,CWnd::FromHandle(hWndParent), hInst))
{
if (m_nFlags & WF_CONTINUEMODAL)
{
// 进入模式循环
DWORD dwFlags = MLF_SHOWONIDLE;
if (GetStyle() & DS_NOIDLEMSG) dwFlags |= MLF_NOIDLEMSG;
VERIFY(RunModalLoop(dwFlags) == m_nModalResult);
}
}
}
CATCH_ALL(e)
{
DELETE_EXCEPTION(e);
m_nModalResult = -1;
}
END_CATCH_ALL
file://Enable 父窗口
if (bEnableParent)
::EnableWindow(hWndParent, TRUE);
if (hWndParent != NULL && ::GetActiveWindow() == m_hWnd)
::SetActiveWindow(hWndParent);
// 删除对话框
DestroyWindow();
PostModal();
… …
}
可以看到,在此实现代码中,并没有开辟新的线程。系统是在RunModalLoop()中进行消息循环。当 m_nFlags 为 WF_CONTINUEMODAL时,系统继续模式状态。RunModalLoop()函数实际上也是一for(;;)循环,控制重新分派Windows消息。直到ContinueModal()返回FALSE,而当调用EndModalLoop()时,ContinueModal()返回FALSE。此时,标志着模态显示的结束。因此,实现模态对话框消息处理的核心部分为RunModalLoop()和EndModalLoop()函数。
三、以模态的形式显示应用到文档/视图框架结构实例
(1)新建一工程文件:ModeFrame,选取MFC AppWizard(exe)。
(2)第二步选取Single document(单文档)。
(3)其余几步均为缺省值。
(4)用ClassWizard添加一新类CSubModeFrame,以CFrameWnd为基类。
(5)添加CsubModeFrame的实现函数DoMode();
int CsubModeFrame::DoModal()
{
HWND hWndParent = m_hWndPrt;
CRect rc(0,0,400,400);
CWnd *pParent = CWnd::FromHandle(hWndParent);
DWORD dwStyle=WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_THICKFRAME | WS_VISIBLE | WS_SYSMENU | WS_CAPTION;
if(!Create(NULL,"模态文档/试图框架 ",dwStyle,rc,pParent,NULL)) return FALSE;
BOOL bEnableParent = FALSE;
if (hWndParent != NULL && ::IsWindowEnabled(hWndParent))
{
::EnableWindow(hWndParent,FALSE);
::EnableWindow(m_hWnd,TRUE);
bEnableParent = TRUE;
}
CenterWindow();
TRY
{
// enter modal loop
DWORD dwFlags = MLF_SHOWONIDLE;
if (GetStyle() & DS_NOIDLEMSG) dwFlags |= MLF_NOIDLEMSG;
VERIFY(RunModalLoop(dwFlags) == m_nModalResult);
}
CATCH_ALL(e)
{
DELETE_EXCEPTION(e);
m_nModalResult = -1;
}
END_CATCH_ALL
if (bEnableParent)
::EnableWindow(hWndParent, TRUE);
if (hWndParent != NULL && ::GetActiveWindow() == m_hWnd)
::SetActiveWindow(hWndParent);
// destroy modal window
DestroyWindow();
return m_nModalResult;
}
(6)添加CsubModeFrame的实现函数EndMode()
void CSubFrame::EndModal(){
ASSERT(::I