Search code examples
winapivb6system-traytrayicon

Handling both mouse move and mouse click on a tray icon


My VB6 application is usually hidden and has a tray icon. It currently handles a user-defined callback as per this code:

Public Const WM_USER = &H400
Public Const TRAY_CALLBACK = (WM_USER + 1001&)
With GTStruct
    .uID = mId
    .hwnd = frm.hwnd
    .hIcon = frm.Icon.Handle
    .UFlags = NIF_ICON Or NIF_MESSAGE
    .uCallbackMessage = TRAY_CALLBACK        
    .cbSize = Len(GTStruct)
End With
Shell_NotifyIcon NIM_ADD, GTStruct

A WindowProc handles TRAY_CALLBACK and the click message:

Const WM_NCDESTROY = &H82
Const WM_CLOSE = &H10

' If we're being destroyed, remove the tray icon
' and restore the original WindowProc.
If Msg = WM_NCDESTROY Or Msg = WM_CLOSE Then
    RemoveFromTray
ElseIf Msg = TRAY_CALLBACK Then
    ' The user clicked on the tray icon.
    ' Look for click events.
    If lParam = WM_RBUTTONUP Then
        ' On right click, show the menu.
        SetForegroundWindow TheForm.hwnd
        TheForm.PopupMenu TheMenu
        If Not (TheForm Is Nothing) Then
            PostMessage TheForm.hwnd, WM_NULL, ByVal 0&, ByVal 0&
        End If
        Exit Function
    End If
End If

As it is, the application works and right-clickign the icon brings up the menu. I want to handle the mouse_move message in addition to this existing callback message so I changed the callback to this:

.uCallbackMessage = TRAY_CALLBACK Or WM_MOUSEMOVE 

However, this ignores the mousemove message. If I use :

.uCallbackMessage = WM_MOUSEMOVE 

The mouse_move message works and Form_MouseMove is called properly but then the menu stops working.

The question

How can I specify multiple callbacks in order to handle both the mouse move and the mouse click?


Solution

  • You can only have one callback message per icon; in your case, this is TRAY_CALLBACK. When you receive this message the lParam value indicates which mouse message triggered your callback.

    In your example code you're already comparing lParam against WM_RBUTTONUP. You just need to add an additional check against WM_MOUSEMOVE.