Quantcast
Channel: codexpert blog » CBT Hook
Viewing all articles
Browse latest Browse all 2

AfxMessageBox with Auto-close – Part 2

0
0

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!

AfxMessageBox with Auto-close

AfxMessageBox with Auto-close

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.
    void CAutoMessageBox::_InitStaticTextCtrl()
    {
       // search for static text control
       CWnd* 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 text
             pWndCtrl->GetWindowText(m_strIntitalText);
             // calculate extra-line height and width
             CClientDC 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 space
             CRect 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 control
          pWndCtrl = pWndCtrl->GetWindow(GW_HWNDNEXT); 
       }
    }
  • CAutoMessageBox::_SetStaticTextCtrl – sets the text which contains time left.
    void 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

Downloads


Viewing all articles
Browse latest Browse all 2

Latest Images

Trending Articles





Latest Images