= MLF_NOIDLEMSG;
VERIFY(RunModalLoop(dwFlags) == m_nModalResult); //进入消息循环
}
.......
}
}
...... 释放资源等
}
原来,DoModal 并不使用 DialogBox 直接调出对话框,而是通过创建无模式对话框并维护消息循环的方式(RunModalLoop)来模拟模式对话框的效果。(看起来好像有点像DialogBox 的内部作业方式)MLF_SHOWONIDLE 是什么?看英文的意思是在Idle 的时候ShowWindow。那么是不是这样呢?好吧,为了探个究竟,让我们进入RunModalLoop。RunModalLoop在WinCore.CPP中定义。打开WinCore.CPP 并找到 RunModalLoop, 会看到以下的语句
BOOL bShowIdle = (dwFlags & MLF_SHOWONIDLE) && !(GetStyle() & WS_VISIBLE);
条件 dwFlags & MLF_SHOWONIDLE 始终为TRUE。 而 !(GetStyle() & WS_VISIBLE)只有在WS_VISIBLE属性没有设置的时候才会为 TRUE。这样,当我们去掉Visible 属性后 bShowIdle 就为 TRUE 了。再往下,就会看到以下的调用
while (bIdle &&
!::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE))
{
ASSERT(ContinueModal());
// show the dialog when the message queue goes idle
if (bShowIdle) // 找到了
{
ShowWindow(SW_SHOWNORMAL);
UpdateWindow();
bShowIdle = FALSE; // 指示下一次Idle 时不用显示对话框了
}
While 里的条件是消息队列里再也没有任何消息了。此时,由于 bShowIdle 为 TRUE ,就会调用 ShowWindow 来显示对话框。由于 ShowWindow 只执行一次,所以如果能截获第一次WM_SHOWWINDOW消息, 就能控制了隐藏了。
是的。在 CTestDlg 处理 WM_SHOWWINDOW 并添上以下代码
void CTestDlg::OnShowWindow(BOOL bShow, UINT nStatus)
{
if( GetStyle() & WS_VISIBLE ) {
CDialog::OnShowWindow(bShow, nStatus);
} else {
long Style = ::GetWindowLong(*this, GWL_STYLE);
::SetWindowLong(*this, GWL_STYLE, Style (北联网教程,专业提供视频软件下载)
……