1

I have an application which is in system tray. I want to make it visible when the user clicks on the notifyIcon, if it's not visible already. If it is already visible it should be hidden. Also when the user clicks anywhere else except on the form the form should hide (if it's visible).

My code looks like this:

protected override void OnDeactivated(EventArgs e)
{
    showForm(false);
}

public void showForm(bool show)
{
    if(show)
    {
        Show();
        Activate();
        WindowState = FormWindowState.Normal;
    }
    else
    {
        Hide();
        WindowState = FormWindowState.Minimized;
    }
}

private void notifyIcon1_MouseClicked(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        if (WindowState != FormWindowState.Normal)
        {
            showForm(true);
        }
    }
}

The problem with the code is that onDeactivated gets called before the click call, which hides the form and notifyIcon1_MouseClicked than just re-shows it. If I could detect if the focus was lost due to a click on notifyIcon or elsewhere it would solve the problem.

I've done my research and found a similar thread, but the solution just detected if the mouse position is over the tray when onDeactivated gets called: C# toggle window by clicking NotifyIcon (taskbar icon)

UPDATE: The solution I posted only detects if the user's mouse is over the tray icons in the taskbar, so if you click on any other tray the onDeactivated event won't get fired. I want to get the same functionality as the system volume app.

Community
  • 1
  • 1
blejzz
  • 3,349
  • 4
  • 39
  • 60
  • You found solution to check if mouse is over notifyicon...so check in ondeactivated event and if mouse is over - dont execute `showForm(false);` or I missed something? – Renatas M. Sep 05 '11 at 14:13
  • the solution detects if the mouse is over the system tray(taskbar), not over my icon. And also the focus lost event gets fired when icon is placed in the notification window – blejzz Sep 05 '11 at 14:23
  • You can use NotifyIcon.MouseMove event to detect when mouse is over icon. But then you need to know when mouse leaves icon area... :/ – Renatas M. Sep 05 '11 at 14:52
  • mousemove event gets fired after the form loses focus – blejzz Sep 05 '11 at 15:13

1 Answers1

5

Simply keep track of the time when the window was last hidden. And ignore the mouse click if that happened recently. Like this:

int lastDeactivateTick;
bool lastDeactivateValid;

protected override void OnDeactivate(EventArgs e) {
    base.OnDeactivate(e);
    lastDeactivateTick = Environment.TickCount;
    lastDeactivateValid = true;
    this.Hide();
}

private void notifyIcon1_MouseClick(object sender, MouseEventArgs e) {
    if (lastDeactivateValid && Environment.TickCount - lastDeactivateTick < 1000) return;
    this.Show();
    this.Activate();
}

Clicking the icon repeatedly now reliably toggles the window visibility.

Vadim Ovchinnikov
  • 13,327
  • 5
  • 62
  • 90
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536