MFC, invisible dialog app with timer
Hello
I'm making a MFC program that needs to start invisible, with a timer running. Then on timer expiry, if certain conditions are met, a dialog is supposed to display. I am trying a Dialog based application because that seems the most straightforward. I have been able to get roughly what I want with the standard modal dialog code generated by Visual Studio, by putting ShowWindow(SW_HIDE) in the dialog's OnPaint method. That approach causes a flicker of the dialog when the program is starting and I think there is a more correct way.
I have also tried:
Code:
BOOL CMyApp::InitInstance()
{
InitCommonControls();
CWinApp::InitInstance();
m_pMainWnd = new CMyDlg;
UINT_PTR uTimerId = SetTimer(NULL, 0, 2000, &TimerCallback);
return (m_pMainWnd != NULL);
}
But this causes an assertion failure in CDialog at
Code:
BOOL CDialog::PreTranslateMessage(MSG* pMsg)
{
// for modeless processing (or modal)
ASSERT(m_hWnd != NULL);
}
It makes sense that m_hWnd is NULL because I haven't called the dailog's DoModal method but I don't know what to do about it.
What is the correct technique for this kind of application?
Thanks.
Re: MFC, invisible dialog app with timer
Call the Dialog's Create method, followed by ShowWindow(SW_HIDE).
Re: MFC, invisible dialog app with timer
Another approach is to handle the OnWindowPosChanging message in the dialog.
First, just use the standard InitInstance:
Code:
BOOL CTestApp::InitInstance()
{
// std initialization removed for demo
CTestDlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
return[SIZE=2] FALSE;
}
Add a timer variable and a variable to keep track of visibility state. Add to the class decl and init in the ctor
Code:
CTestDlg::CTestDlg(CWnd* pParent /*=NULL*/[SIZE=2])
: CDialog(CTestDlg::IDD, pParent)
, m_uTimerId( NULL )
, m_bVisible( FALSE )
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
Start the timer in OnInitDialog.
Code:
BOOL CTestDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// std initialization removed for demo
// Start the timer
m_uTimerId = SetTimer( 1, 4000, NULL );
return TRUE;
}
Handle the timer message. Set the visible variable to true, show
the dialog, and kill the timer:
Code:
void CTestDlg::OnTimer(UINT_PTR nIDEvent)
{
m_bVisible = TRUE;
ShowWindow( SW_SHOW );
KillTimer( m_uTimerId );
CDialog::OnTimer(nIDEvent);
}
Handle the OnWindowPosChanging message. If the m_bVisible variable is false, remove the show window style
Code:
void CTestDlg::OnWindowPosChanging(WINDOWPOS* lpwndpos)
{
if( !m_bVisible )
{
lpwndpos->flags &= ~SWP_SHOWWINDOW;
}
CDialog::OnWindowPosChanging(lpwndpos);
}
Re: MFC, invisible dialog app with timer
Re: MFC, invisible dialog app with timer
Quote:
Originally Posted by
Msm
use [CODE RunModalLoop()[/CODE]
Where an hat for? :confused:
RunModalLoop is used internally within CDialog::DoModal
Use Arjay's approach: it will work good!