Question

I have a NotifyIcon in the system tray. How can I detect when the user has left-clicked down on it? I assumed the MouseDown event would be what I want to use but it only handles right click and middle-button click. For left-click, it only fires after the user has let go (as in they've just performed a normal click). Is there a way to get the MouseDown event only?

Was it helpful?

Solution

This is by design, the shell synthesizes the MouseDown message from the up event. You'll see why it works this way when you click and hold the button down and then start dragging. Note how the notification area overflow window pops up and lets you drag the icon into it to remove it from the visible area. It can't work both ways.

Technically you could hook the window owned by Explorer.exe to get a crack at the messages before Explorer does with SetWindowsHookEx(). That however requires a kind of DLL that you cannot write in C#, it needs to be injected into Explorer. Very destabilizing and hard to beat the competition that is trying to do the same thing. Also the kind of code that causes sleepless nights for the Microsoft appcompat team.

OTHER TIPS

It appears that the underlying Win32 API Shell_NotifyIcon sends a WM_LBUTTONDOWN message when the user clicks the icon. According to MSDN anyway.

Examining the Windows Forms source code for NotifyIcon reveals standard mouse down event handling, so if the Win32 message was being sent at the "correct" time it would work as you want/expect.

I have to agree with a previous comment that NotifyIcon will be swallowing WM_LBUTTONDOWN since it needs to do mouse capture to allow the user to drag the icons about.

It's possible that this article about creating a tray icon for WPF will be useful since it shows how to use SetWindowsHookEx etc from C#.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top