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

断了今生、忘了曾经 提交于 2019-12-02 08:54:59

@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();
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!