How to Implement a Mouse Hover/Leave Message on the System Tray

WEBINAR: On-demand webcast

How to Boost Database Development Productivity on Linux, Docker, and Kubernetes with Microsoft SQL Server 2017 REGISTER >


Introduction

This article illustrates how to implement a tray mouse hover/leave message.

The Problem

Some programs want to get a mouse hover/leave message from the system tray when they want to show a popup window that is not a tool tip. However, the Windows shell doesn't support it. We can only get mouse move, up, down, and double-click messages from the system tray.

It is very easy to implement a WM_MOUSEHOVER message because the first WM_MOUSEMOVE is that. But, WM_MOUSELEAVE is hard to implement, so I decided to write a compact class to notify the window of a mouse hover/leave message.

The Idea

The basic idea is very simple. It is that no WM_MOUSEMOVE message fires when the mouse is out of the tray icon. This class saves the mouse point whenever a WM_MOUSEMOVE message fires on the system tray, and then another thread compares it with the current mouse point. The thread fires a WM_MOUSELEAVE message when the two points are different.

The following code is the WM_MOUSEMOVE handler.

VOID CTrayPos::OnMouseMove()
{
   EnterCriticalSection(&m_cs);

   GetCursorPos(&m_ptMouse);
   if(m_bTrackMouse == FALSE)
   {
      OnMouseHover();
      m_bTrackMouse = TRUE;
   }

   LeaveCriticalSection(&m_cs);
}

This is a thread function that checks the mouse point.

UINT CALLBACK CTrayPos::TrackMousePt(PVOID pvClass)
{
   POINT       ptMouse;
   CTrayPos    *pTrayPos = (CTrayPos *) pvClass;

   while(WaitForSingleObject(pTrayPos->m_hExitEvent, 2000) ==
                             WAIT_TIMEOUT)
   {

      if(pTrayPos->m_bTrackMouse == TRUE)
      {
         GetCursorPos(&ptMouse);

         if(ptMouse.x != pTrayPos->m_ptMouse.x || ptMouse.y !=
            pTrayPos->m_ptMouse.y)
         {
            pTrayPos->m_bTrackMouse = FALSE;
            pTrayPos->OnMouseLeave();
         }
      }
   }

   return 0;
}

Using the Code

If you want to use this class in your project, just follow these simple steps.

  • Add traypos.h and traypos.cpp file to your project.
  • Declare a variable of this class like that.
    Note that this class instance exists until the tray icon is deleted, so you must declare it a member variable or a global variable.
  • CMsgTrayPos traypos;
  • Add the following code after the register tray by calling Shell_NotifyIcon.
    The three parameters—hwnd, uID, and uMsgID—are the same value as the member of NOTIFYICONDATA.
  • traypos.SetNotifyIconInfo(hwnd, uID, uMsgID);
  • Call CMsgTrayPos::OnMouseMove on your WM_MOUSEMOVE message handler from the system tray.
  • Now, you can add WM_MOUSEHOVER and WM_MOUSELEAVE messages to your tray message handler and write a code there.

CMsgTrayPos API

  • VOID CMsgTrayPos::SetNotifyIconInfo(HWND hwnd, UINT uID, UINT uCallbackMsg);
    This function provides tray icon inforamtion to the class. The three parameters—hwnd, uID, and uCallbackMsg—and members of NOTIFYICONDATA are the same.
  • VOID CMsgTrayPos::OnMouseMove()

  • This function is very important. You must call this function when you get a WM_MOUSEMOVE message from the system tray.
    This function checks the mouse hover status and updates the mouse point internally.
  • BOOL CMsgTrayPos::IsIconHover();
    This function returns the mouse hover status. It returns TRUE if your mouse is on your tray icon.

History

  • 22 Aug 2004—Initial upload.


Downloads

Comments

  • Nice legs

    Posted by Artipol on 07/22/2008 06:05am

    That girl has a very nice-looking pair of legs.

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

Top White Papers and Webcasts

  • Whether a mandate to secure all web and mobile apps comes from a newly enlightened CIO or in response to a major security breach, beginning even a small application security program can be a daunting task. How will you know how many digital assets you have, let alone their risk profile? In this webinar we explore how, using a cloud solution like Fortify on Demand, even the largest organizations can begin to scan apps immediately and rapidly scale an application security program. Identify and risk rank assets, …

  • Event Date: Tues, December 5, 2017 at 1:00 p.m. ET/10:00 a.m. PT Modernizing the enterprise data center to address raging demands for speed, performance, and capacity is a top directive for many IT organizations. While it's a known fact that upgrading to next-generation flash and solid-state drives (SSDs) can improve IT agility and application performance, the lower cost of legacy hard-disk drives (HDDs) has confined SSD use to only 10% of the data center. But that's changing. Don't guesstimate the …

Most Popular Programming Stories

More for Developers

RSS Feeds

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