Using TrackMouseEvent to find out when the mouse leaves your window


Full Text Search: The Key to Better Natural Language Queries for NoSQL in Node.js

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

  • IT planners have far more options as to where to run their workloads than ever before. On-premises data centers, co-location facilities and managed services providers are now joined by hybrid multi-clouds – a combination of Software-, Infrastructure- and Platform-as-a-Service (SaaS, IaaS, and PaaS) execution venues. All have unique operational, performance and economic characteristics that need to be considered when deploying workloads. Submit the form to watch this webinar replay featuring 451 …

  • Cloud has the potential to offer many benefits that can enable great success within your business. However, there are still many myths floating around about backing up to the cloud. In this eBook, you'll discover the truth about five of the most common cloud myths, including myths about security, maintaining regulatory compliance and more. Get to the truth, so you can backup to the cloud with confidence.

Most Popular Programming Stories

More for Developers

RSS Feeds

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