Using TrackMouseEvent to find out when the mouse leaves your window

Using TrackMouseEvent is pretty simple. When the mouse enters the window you want to track, you call track mouse event telling it to inform you when the mouse leaves. When it does, it will send a WM_MOUSELEAVE message to that window.

If you add this code to any of your existing view classes (or any CWnd derived class), you will see a drag rectangle that follows the mouse cursor around. If you move the mouse outside the window, it will disappear. If you move the mouse back into the window, it will reappear.


// TrackView.h changes

class CTrackView : public CView
// Add data members
	CRect m_rectLast;	//** Added line
	BOOL m_bMouseTracking;	//** Added line

// Add message handler prototype
	afx_msg LRESULT OnMouseLeave(WPARAM wParam, LPARAM lParam);	//** Added line



// TrackView.cpp changes

// Add message handler
	ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)	//** Added line

	m_bMouseTracking = FALSE;	//** Added line

// CTrackView message handlers

//** Added function
LRESULT CTrackView::OnMouseLeave(WPARAM wParam, LPARAM lParam)
	// Draw last rect, but no new one (erase old rect)
	CClientDC dc(this);
	dc.DrawDragRect(CRect(0,0,0,0), CSize(0,0), m_rectLast, CSize(2,2));
	m_rectLast = CRect(0,0,0,0);

	m_bMouseTracking = FALSE;
	return TRUE;

void CTrackView::OnMouseMove(UINT nFlags, CPoint point) 
	// Calc new rectangle
	CRect rectNew(point.x-20, point.y-20, point.x+20, point.y+20);
	CClientDC dc(this);

	// WM_MOUSEMOVE + !m_bMouseTracking becomes the equivalent of
	// WM_MOUSEENTER of which there is no such thing.
	if (!m_bMouseTracking)
		tme.cbSize = sizeof(TRACKMOUSEEVENT);
		tme.dwFlags = TME_LEAVE;
		tme.hwndTrack = this->m_hWnd;
		if (::_TrackMouseEvent(&tme))
			m_bMouseTracking = TRUE;
			// Draw new rect, but no last rect as we are starting anew
			dc.DrawDragRect(rectNew, CSize(2,2), NULL, CSize(0,0));
		// Draw new rect and erase old rect
		dc.DrawDragRect(rectNew, CSize(2,2), m_rectLast, CSize(2,2));

	// Remember where we drew this rectangle
	m_rectLast = rectNew;

	CView::OnMouseMove(nFlags, point);


Here's a helper class I use to make it a little simpler:

class CTrackMouseEvent : public tagTRACKMOUSEEVENT
	CTrackMouseEvent(CWnd* pWnd, DWORD dwFlags = TME_LEAVE, DWORD dwHoverTime = HOVER_DEFAULT)

		this->cbSize = sizeof(TRACKMOUSEEVENT);
		this->dwFlags = dwFlags;
		this->hwndTrack = pWnd->m_hWnd;
		this->dwHoverTime = dwHoverTime;

	BOOL Track()
		{ return _TrackMouseEvent(this); }

You can start tracking like this:

if (!m_bMouseTracking)
	m_bMouseTracking = CTrackMouseEvent(this).Track();


  • Why is does & doesn't work '_'

    Posted by Legacy on 04/12/2002 12:00am

    Originally posted by: James White

    This is just a guess, but I would think the reason it does work on some systems and doesn't on others is the _ you prefix the TrackMouseEvent function with. I read somewhere that the _TrackMouseEvent is an IE implemented funciton where TrackMouseEvent is part of the Win32 API (post 95). That could explain why some people see it work and some don't.

  • Easier way to track mouse out event

    Posted by Legacy on 01/16/2002 12:00am

    Originally posted by: Z Mohamed Mustafa

    Easier way to track mouse out event
    To track the mouse leave event I have used the following method hope it helps.

    Step 1:
    Add the following members in your window class in which you want to track the mouse out event.

    BOOL bTracking;
    afx_msg void OnMouseMove(UINT nFlags, CPoint point);
    //default mouse move handler.
    afx_msg void OnMouseLeave();
    //user defined mouse leave handler

    Step 2:
    Initialize bTracking = false; in the constructor.

    Step 3:
    Add the code snippet in your handlers

    void YourWndClass::OnMouseMove(UINT nFlags, CPoint point)
    // TODO: Add your message handler code here
    // and/or call default
    // Do not track if already tracking

    tme.cbSize = sizeof(tme);
    tme.dwFlags = TME_LEAVE;
    tme.hwndTrack = m_hWnd;
    tme.dwHoverTime = HOVER_DEFAULT;
    bTracking = true;
    // Your extra coding on mouse move goes here....
    BaseClass::OnMouseMove(nFlags, point);

    void YourWndClass::OnMouseLeave()
    // after MouseLeave no tracking is done.
    // When the mouse leaves the window this function
    // is fired.
    // Your extra coding on mouse leave goes here....

    bTracking = false;

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Entire organizations suffer when their networks can't keep up and new opportunities are put on hold. Waiting on service providers isn't good business. In these examples, learn how to simplify network management so that your organization can better manage costs, adapt quickly to business demands, and seize market opportunities when they arise.

  • This IDC study assists senior IT leaders in assessing the current state of their hybrid cloud management processes, governance models, technologies, and skills to identify gaps and create a road map for better aligning the organization's management model and tools with the emerging needs of complex, dynamic self-service hybrid cloud environments. This IDC MaturityScape identifies five maturity stages for hybrid cloud management based on a set of specific people, process, and technology dimensions and outcomes. …

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date