In a previous article I showed how to make AfxMessageBox to display a message box with auto-close, by using a CBT hook.
One reader suggested that whould be nice if the message box displays also the time left until auto-closing. I thought that’s a very good idea and promissed an update. Here it is!
Of course, may be more than one solution. I chose one which appends “Time left: xxx sec.” in the bottom of the built-in static text control. For this purpose, I added two private methods to CAutoMessageBox class:
- CAutoMessageBox::_InitStaticTextCtrl – initializes the static contol: finds the static control, keeps in mind the initial text, makes space for an extra-line of text, and assigns an ID to be used later.
12345678910111213141516171819202122232425262728293031323334353637383940414243void CAutoMessageBox::_InitStaticTextCtrl(){// search for static text controlCWnd* pWndCtrl = GetWindow(GW_CHILD);while(NULL != pWndCtrl->GetSafeHwnd()){const int nMaxCount = 63;CString strClass;::GetClassName(pWndCtrl->m_hWnd,strClass.GetBufferSetLength(nMaxCount), nMaxCount);DWORD dwStyle = pWndCtrl->GetStyle();strClass.ReleaseBuffer();if(!strClass.CompareNoCase(_T("STATIC"))&& !(dwStyle & SS_ICON)){// set static control ID::SetWindowLong(pWndCtrl->m_hWnd, GWL_ID, IDC_STATIC_TEXT);// keep in mind the initial textpWndCtrl->GetWindowText(m_strIntitalText);// calculate extra-line height and widthCClientDC dc(this);CFont* pFont = pWndCtrl->GetFont();ASSERT(NULL != pFont);CFont* pOldFont = dc.SelectObject(pFont);CRect rcText(0, 0, 0, 0);dc.DrawText(CString(_T("Time left: 999 sec.")), rcText,DT_SINGLELINE|DT_CALCRECT);dc.SelectObject(pOldFont);// add extra-line spaceCRect rcCtrl;pWndCtrl->GetWindowRect(rcCtrl);ScreenToClient(rcCtrl);rcCtrl.bottom += rcText.Height();const int nExtraWidth = rcText.Width() - rcCtrl.Width();if(nExtraWidth > 0)rcCtrl.right += nExtraWidth;pWndCtrl->MoveWindow(rcCtrl);break;}// get next child controlpWndCtrl = pWndCtrl->GetWindow(GW_HWNDNEXT);}} - CAutoMessageBox::_SetStaticTextCtrl – sets the text which contains time left.
1234567891011void CAutoMessageBox::_SetStaticTextCtrl(){UINT nRemained = (m_nTimeOut - m_nElapsed) / 1000 + 1;CWnd* pWndStatic = GetDlgItem(IDC_STATIC_TEXT);ASSERT(NULL != pWndStatic->GetSafeHwnd());CString strText;strText.Format(_T("%s\nTime left: %u sec."),m_strIntitalText, nRemained);pWndStatic->SetWindowText(strText);}
For more implementation details of CAutoMessageBox class, download and have a look in the attached demo project.
See also
- Codexpert blog: AfxMessageBox with Auto-close (Part 1)