Adding Delays to TitleTips

The TitleTip that I created does not include any of the delay features provided by the TTM_SETDELAYTIME message of a standard ToolTip. I didn't add any delays because Microsoft doesn't appear to have added any delays to its TitleTip implementation either. However, most other types of tips do have delays built in, so in case you want to add delays to your own custom tips, I want to explain how to add them.
In general, the delays involve the use of window timers. CWnd provides two functions related to timers: CWnd::SetTimer and CWnd::KillTimer. CWnd::SetTimer sets a timer and takes a timer ID, a timeout value in milliseconds, and a function pointer to a timer handler as parameters. If the function pointer is NULL, then it uses the WM_TIMER message to notify the window of a timer event. CWnd::KillTimer stops a timer and takes a timer ID of the timer to stop as a parameter.
Given this support for timers, let's see how you can add delays to a custom tip. I'm going to show you how to add the equivalent of the TTDT_AUTOPOP feature of the TTM_SETDELAYTIME message. This is the delay before the tip is automatically hidden if the cursor does not move.
First, add member variables to the protected or private section of the custom tip class to store the timer ID and the position of the cursor when the tip was displayed. Also, add a constant to store the delay time before the tip is automatically hidden. The code would look like this:
class CCustomTip: public CWnd
 {
 .
 .
 .
 protected:
     const int m_nAutoPopDelay; // In milliseconds.
     UINT m_nTimerId;
     CPoint m_LastMousePosition;
 .
 .
 .
 };
Initialize the m_nAutoPopDelay to 10000 (ten seconds) and the m_nTimerId to zero in the constructor.
CCustomTip::CCustomTip
 : m_nAutoPopDelay(10000), m_LastMousePosition(0, 0)
 {
 .
 .
 .
 m_nTimerId = 0;
 .
 .
 .
 }
You can actually set the delay to whatever you want—I chose ten seconds for demonstration purposes.
Add code to start the timer when the tip is shown. For instance, if there was a CCustomTip::Show member function, you would add the following code to the method that shows the window:
void CCustomTip::Show
 {
 .
 .
 .
     if (m_nTimerId > 0)
     {
         VERIFY(KillTimer(m_nTimerId));
         m_nTimerId = 0;
     }
     VERIFY(::GetCursorPos(&m_LastMousePosition));
     m_nTimerId = SetTimer(1, m_nAutoPopDelay, NULL);
     ASSERT(m_nTimerId != 0);
 .
 .
 .
 }
Add code to handle the timer message. Use ClassWizard to add a WM_TIMER handler to the message map. The handler code should look like the following:
void CTitleTip::OnTimer(UINT nIDEvent)
 {
     CPoint CurrentMousePosition;
 
     VERIFY(::GetCursorPos(&CurrentMousePosition));
     if (CurrentMousePosition == m_LastMousePosition)
     {
         Hide();
     }
     else
     {
         m_LastMousePosition = CurrentMousePosition;
     }
 }
Finally, add code to the CCustomTip::Hide member to kill the timer:
void CCustomTip::Hide()
 {
     if (m_nTimerId > 0)
     {
         VERIFY(KillTimer(m_nTimerId));
         m_nTimerId = 0;
     }
     ShowWindow(SW_HIDE);
 }
You would use similar coding techniques to add the other types of delays built into standard ToolTips, but you would have to keep track of more state changes than just cursor position. For example, suppose you want to add the equivalent of the TTDT_RESHOW feature. This is the amount of time before another ToolTip is displayed when the cursor is moved from one item (or tool) to another. You would have to create member variables to keep track of when the last ToolTip was hidden and what it contained.