从通知图标激活我的主窗体的正确方法(如果它尚未聚焦)

本文关键字:如果 方法 聚焦 激活 图标 通知 我的 窗体 | 更新日期: 2024-11-07 16:01:35

我只想用托盘通知图标替换我的 winforms 应用程序的任务栏按钮。这意味着,如果用户左键单击图标,则应激活表单(如果未聚焦),否则应将其最小化或隐藏。

我阅读了很多关于正确使用NotifyIcon的文章,似乎我必须接受一个黑客解决方案。那么,最正确的方法是什么?

让它主要是为了运行,但现在我只能检测我的表单是否已经处于活动状态 - 因为单击图标时,表单会失去焦点,所以我无法检查 Focused 属性。

下面的代码还没有解决这个问题,所以如果表单只是被其他窗口隐藏,你必须点击 2 次,因为第一次点击会最小化。

如何改进?

    private void FormMain_Resize(object sender, EventArgs e)
    {
        if (WindowState == FormWindowState.Minimized)
            Hide();
    }
    private void notifyIcon_MouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
            if (WindowState == FormWindowState.Minimized) {
                WindowState = FormWindowState.Normal;
                Show();
                Activate();
            }
            else {
                Hide();
                WindowState = FormWindowState.Minimized;
            }
    }

(我也不明白为什么右键单击时会触发Click事件,这在我的情况下已经打开了上下文菜单......

(当然,有一个适当的最小化动画会很好,但这里还有其他问题,这并没有真正解决)

(我知道我说Focused,但如果表单已经完全可见(但可能没有聚焦),并且用户单击托盘图标,他很可能想要隐藏它)

从通知图标激活我的主窗体的正确方法(如果它尚未聚焦)

@LarsTech建议使用计时器进行黑客攻击,这有效,谢谢,但我仍然希望有更好的解决方案或改进。

也许有趣:我还破解了部分动画问题 - 当没有任务栏按钮时,动画来自最小化表单所在的位置。您可以通过在最小化后调用Show()来使其可见。它位于屏幕的左下角,无法通过设置即Left属性来移动它。所以我直接使用了 winapi,它有效!不幸的是,仅适用于恢复动画,因为我不知道如何在最小化之前设置最小化的位置。 无论如何,Hide()禁用动画,所以我不得不延迟它......

这一切都太令人失望了!为什么没有好的解决方案?我永远无法确定它是否适用于每种情况。例如,在一台机器上,它与 100 毫秒的计时器配合得很好,但在另一台机器上我需要 200 毫秒。所以我建议至少有 500 毫秒。

[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();
}
相关文章: