什么是最小化托盘C#WinForms应用程序的正确方法是什么?

时间:2008-09-05 21:20:47

标签: c# winforms trayicon

将WinForms应用最小化到系统托盘的正确方法是什么?

注意:最小化为 系统托盘 ;在时钟任务栏的右侧。我不是要问最小化到任务栏,当你点击窗口上的“减号”按钮时会发生这种情况。

我见过像这样的黑客解决方案,“最小化,设置ShowInTaskbar = false,然后显示你的NotifyIcon。”

像这样的解决方案是hackish,因为应用程序似乎没有像其他应用程序那样最小化托盘,代码必须检测何时设置ShowInTaskbar = true,以及其他问题。

这样做的正确方法是什么?

9 个答案:

答案 0 :(得分:18)

实际上没有管理方式在本机winforms中对托盘执行这种形式的动画,但是你可以通过P / Invoke shell32.dll来执行此操作:

这里有一些好消息(在评论中不是帖子):

http://blogs.msdn.com/jfoscoding/archive/2005/10/20/483300.aspx

这里是C ++:

http://www.codeproject.com/KB/shell/minimizetotray.aspx

您可以使用它来确定Pinvoke为您的C#版本提供的内容。

答案 1 :(得分:8)

this.WindowState = FormWindowState.Minimized  

这是内置的方式,它在大多数时候对我来说很好看。唯一的一次是有一些奇怪的是,如果你在启动时调用它有时会有些奇怪,这就是为什么大多数人也会设置ShowInTaskbar = false并隐藏表单。

http://msdn.microsoft.com/en-us/library/system.windows.forms.form.windowstate.aspx

答案 2 :(得分:5)

这会有所帮助:

public partial class Form1 : Form
{
    public static bool Close = false;
    Icon[] images;
    int offset = 0;

    public Form1()
    {
        InitializeComponent();

        notifyIcon1.BalloonTipText = "My application still working...";
        notifyIcon1.BalloonTipTitle = "My Sample Application";
        notifyIcon1.BalloonTipIcon = ToolTipIcon.Info; 
    }

    private void Form1_Resize(object sender, EventArgs e)
    {
        if (FormWindowState.Minimized == WindowState)
        {
            this.Hide();
            notifyIcon1.ShowBalloonTip(500);
            //WindowState = FormWindowState.Minimized;
        }
    }

    private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
    {
        this.Show();
        notifyIcon1.ShowBalloonTip(1000);
        WindowState = FormWindowState.Normal;
    }

    private void maximizeToolStripMenuItem_Click(object sender, EventArgs e)
    {
        this.Show();
        WindowState = FormWindowState.Normal;
    }

    private void closeToolStripMenuItem_Click(object sender, EventArgs e)
    {
        Close = true;
        this.Close();  
    }

    // Handle Closing of the Form.
    protected override void OnClosing(CancelEventArgs e)
    {
        if (Close)
        {
            e.Cancel = false;
        }
        else
        {
            WindowState = FormWindowState.Minimized;
            e.Cancel = true;
        }
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        // Load the basic set of eight icons.
        images = new Icon[5];
        images[0] = new Icon("C:\\icon1.ico");
        images[1] = new Icon("C:\\icon2.ico");
        images[2] = new Icon("C:\\icon3.ico");
        images[3] = new Icon("C:\\icon4.ico");
        images[4] = new Icon("C:\\icon5.ico");
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        // Change the icon.
        // This event handler fires once every second (1000 ms).
        if (offset < 5)
        {
            notifyIcon1.Icon = images[offset];
            offset++;
        }
        else
        {
            offset = 0;
        }
    }
}

答案 3 :(得分:4)

此代码经过测试并支持许多选项。

更多信息:http://code.msdn.microsoft.com/TheNotifyIconExample

答案 4 :(得分:3)

更新:看起来我发布的太快了。 我也使用下面的黑客攻击我的工具。等待正确的解决方案..........

您可以使用Windows.Forms.NotifyIcon。 http://msdn.microsoft.com/en-us/library/system.windows.forms.notifyicon.aspx

将NotifyIcon添加到表单中,设置一些属性,然后就完成了。

        this.ShowIcon = false;//for the main form
        this.ShowInTaskbar = false;//for the main form
        this.notifyIcon1.Visible = true;//for notify icon
        this.notifyIcon1.Icon = ((System.Drawing.Icon)(resources.GetObject("notifyIcon1.Icon")));//set an icon for notifyicon

    private void Form1_Shown(object sender, EventArgs e)
    {
        this.Hide();
    }

答案 5 :(得分:1)

与上述类似......

我有一个resize事件处理程序,只要窗口调整大小(最大化,最小化等)就会触发...

    public form1()
    {
       Initialize Component();

       this.Resize += new EventHanlder(form1_Resize);
    } 


    private void form1_Resize(object sender, EventArgs e)
    {
       if (this.WindowState == FormWindowState.Minimized && minimizeToTrayToolStripMenuItem.Checked == true)
       {
             NotificationIcon1.Visible = true;
             NotificationIcon1.BalloonTipText = "Tool Tip Text"
             NotificationIcon1.ShowBalloonTip(2);  //show balloon tip for 2 seconds
             NotificationIcon1.Text = "Balloon Text that shows when minimized to tray for 2 seconds";
             this.WindowState = FormWindowState.Minimized;
             this.ShowInTaskbar = false;
       }
    }

这允许用户选择是否想要通过菜单栏最小化到托盘。他们可以去Windows - &gt;并单击最小化到托盘。如果选中此项, 并且窗口被调整为最小化,然后它将最小化到托盘。对我来说完美无瑕。

答案 6 :(得分:0)

下午好

我为你们设计了一个快速的解决方案,这可能不是最有效的方法(我不确定),但是绝对可以!!

以下解决方案成功地将Winforms应用程序最小化到系统托盘,并通过使用notify图标,您在系统托盘中使用上述菜单项创建了一个小图标。而不是使用内置库来获取窗口(在本例中为GUI),然后使用带有布尔值的适当方法,然后将窗口最小化到托盘。

private void TransformWindow()
        {
            ContextMenu Menu = new ContextMenu();

            Menu.MenuItems.Add(RestoreMenu);
            Menu.MenuItems.Add(HideMenu);
            Menu.MenuItems.Add(new MenuItem("Exit", new EventHandler(CleanExit)));

            notifyIcon = new NotifyIcon()
            {
                Icon = Properties.Resources.Microsft_Icon,
                Text = "Folder Watcher",
                Visible = true,
                ContextMenu = Menu
            };
            processHandle = Process.GetCurrentProcess().MainWindowHandle;
            ResizeWindow(false);

        }
        #region Getting Libraries
        [DllImport("user32.dll")]
        public static extern IntPtr GetShellWindow();
        [DllImport("user32.dll")]
        public static extern IntPtr GetDesktopWindow();
        public const Int32 SwMINIMIZE = 0;
        public const Int32 SwMaximize = 9;

        [DllImport("Kernel32.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        public static extern IntPtr GetConsoleWindow();

        [DllImport("User32.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool ShowWindow([In] IntPtr hWnd, [In] Int32 nCmdShow);
        public static void MinimizeConsoleWindow()
        {
            IntPtr hWndConsole = processHandle;
            ShowWindow(hWndConsole, SwMINIMIZE);

        }
        public static void MaximizeConsoleWindow()
        {
            IntPtr hWndConsole = processHandle;
            ShowWindow(hWndConsole, SwMaximize);

        }
        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
        public static void ResizeWindow(bool show)
        {
            RestoreMenu.Enabled = !show;
            HideMenu.Enabled = show;
            SetParent(processHandle, WinDesktop);

            if (show)
                MaximizeConsoleWindow();
            else
                MinimizeConsoleWindow();

        }
        public static void MinimizeClick(object sender, EventArgs e) => ResizeWindow(false);
        public static void MaximizeClick(object sender, EventArgs e) => ResizeWindow(true);
        public static IntPtr processHandle;
        public static IntPtr WinShell;
        public static IntPtr WinDesktop;
        public static NotifyIcon notifyIcon;
        public static MenuItem HideMenu = new MenuItem("Hide", new EventHandler(MinimizeClick));
        public static MenuItem RestoreMenu = new MenuItem("Restore", new EventHandler(MaximizeClick));
        public void CleanExit(object sender, EventArgs e)
        {
            notifyIcon.Visible = false;
            this.Close();
        }

答案 7 :(得分:-1)

在Form的构造函数中:

this.Resize += new EventHandler(MainForm_Minimize);

然后使用此事件处理程序方法:

    private void MainForm_Minimize(object sender, EventArgs e)
    {
        if(this.WindowState == FormWindowState.Minimized)
            Hide();
    }

答案 8 :(得分:-1)

如果您在使用此功能时遇到问题,请检查您是否

this.Resize += new System.EventHandler(this.Form1_Resize);
fom1.designer.cs中的