Proper way of activating my MainForm from a NotifyIcon if it wasn't focused already

前端 未结 1 393
礼貌的吻别
礼貌的吻别 2021-01-28 08:16

I just want to replace the task bar button of my winforms application by a tray notification icon. That means, if the user left-clicks the icon, the form should be activated if

相关标签:
1条回答
  • 2021-01-28 09:01

    @LarsTech suggested a hack using a timer, and this works, thanks, but I still hope for better solutions or improvements.

    Maybe interesting: I also hack-solved part of the animation problem - when there is no taskbar button, the animation originates from where the minimized form is located. You can make it visible by calling Show() after minimizing. It sits in the lower left of the screen and it is not possible to move it by setting i.e. the Left property. So I used winapi directly and it works! Unfortunately only for the restore animation, because I don't know how to set the minimized position before minimizing. Hide() disables the animation anyway, so I would have to delay it...

    That all is so disappointing! Why is there no nice solution? I can never be sure if it will work in every scenario. For example on one machine it worked well with a 100ms timer, but on another I needed 200ms. So I suggest to have a least 500ms.

    [DllImport("user32.dll", SetLastError = true)]
    static extern bool MoveWindow(IntPtr hWnd, 
        int X, int Y, int nWidth, int nHeight, bool bRepaint);
    
    private void FormMain_Resize(object sender, EventArgs e)
    {
        if (!ShowInTaskbar && WindowState == FormWindowState.Minimized) {
            Hide();
            //Move the invisible minimized window near the tray notification area
            if (!MoveWindow(Handle, Screen.PrimaryScreen.WorkingArea.Left
                    + Screen.PrimaryScreen.WorkingArea.Width - Width - 100,
                    Top, Width, Height, false))
                throw new Win32Exception();
        }
    }
    
    private void notifyIcon_MouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
            if (WindowState == FormWindowState.Minimized || !timer.Enabled) {
                Show();
                WindowState = FormWindowState.Normal;
                Activate();
            }
            else {
                WindowState = FormWindowState.Minimized;
                //FormMain_Resize will be called after this
            }
    }
    
    private void FormMain_Deactivate(object sender, EventArgs e)
    {
        timer.Start();
    }
    
    private void timer_Tick(object sender, EventArgs e)
    {
        timer.Stop();
    }
    
    //other free goodies not mentioned before...
    
    private void taskbarToolStripMenuItem_Click(object sender, EventArgs e)
    {
        ShowInTaskbar = !ShowInTaskbar;
        taskbarToolStripMenuItem.Checked = ShowInTaskbar;
    }
    
    private void priorityToolStripMenuItem_Click(object sender, EventArgs e)
    {
        //Set the process priority from ToolStripMenuItem.Tag
        //Normal = 32, Idle = 64, High = 128, BelowNormal = 16384, AboveNormal = 32768
        Process.GetCurrentProcess().PriorityClass
            = (ProcessPriorityClass)int.Parse((sender as ToolStripMenuItem).Tag.ToString());
        foreach (ToolStripMenuItem item in contextMenuStrip.Items)
            if (item.Tag != null)
                item.Checked = item.Equals(sender);
    }
    
    private void exitToolStripMenuItem_Click(object sender, EventArgs e)
    {
        Close();
    }
    
    0 讨论(0)
提交回复
热议问题