如何启动WinForm应用程序最小化到托盘?

发布于 2024-08-11 06:26:10 字数 848 浏览 6 评论 0原文

我已经成功创建了一个使用 NotifyIcon 最小化到托盘的应用程序。手动关闭表单后,它会成功地从桌面、任务栏和 alt-tab 中隐藏。尝试以最小化应用程序启动时会出现此问题。最初的问题是应用程序会最小化,但仍会出现在 alt-tab 对话框中。将 FormBorderStyle 更改为 ToolWindow 选项之一(从“None”选项)修复了此问题,但引入了另一个问题。当应用程序首次启动时,最小化窗口的标题栏在开始菜单上方可见:

在此处输入图像描述

打开表单并关闭它会使其正确隐藏。我已经尝试了很多变体,但本质上是它现在的工作方式...

WindowState 在设计器中设置为最小化。在构造函数中进行一些初始化后,我有以下几行:

this.Visible = false;
this.ShowInTaskbar = false;

双击 NotifyIcon 时,我有以下几行:

 this.WindowState = FormWindowState.Normal;
 this.Visible = true;
 this.ShowInTaskbar = true;

正如我所说,我已经尝试了很多对此的细微变化(this.Hide() 等)。有没有办法让 NotifyIcon 成为主要组件,以便我可以在保持 NotifyIcon 运行的同时完全启动和处理表单?必须有一种方法可以在最小化表单的情况下启动应用程序,而不会出现任何奇怪的情况。请帮我找到它!

I've successfully created an app that minimizes to the tray using a NotifyIcon. When the form is manually closed it is successfully hidden from the desktop, taskbar, and alt-tab. The problem occurs when trying to start with the app minimized. At first the problem was that the app would be minimized but would still appear in the alt-tab dialog. Changing the FormBorderStyle to one of the ToolWindow options (from the "None" option) fixed this, but introduced another problem. When the app first starts the titlebar of the minimized window is visible just above the start menu:

enter image description here

Opening the form and the closing it causes it to hide properly. I've tried lots of variations, but here's essentially how it's working right now...

WindowState is set to Minimized in the Designer. After some initialization in the constructor I have the following lines:

this.Visible = false;
this.ShowInTaskbar = false;

When the NotifyIcon is double-clicked I have the following:

 this.WindowState = FormWindowState.Normal;
 this.Visible = true;
 this.ShowInTaskbar = true;

Like I said, I've tried lots of minor variations on this (this.Hide(), etc.). Is there a way to have the NotifyIcon be the primary component such that I can completely start and dispose of the form while leaving the NotifyIcon running? There's got to be a way to start the app with the form minimized without any of the weirdness. Please help me find it!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

南巷近海 2024-08-18 06:26:10

正确的方法是首先防止表单可见。这需要重写 SetVisibleCore()。我们假设 NotifyIcon 的上下文菜单带有“显示”和“退出”命令。您可以像这样实现它:

public partial class Form1 : Form {
    public Form1() {
        InitializeComponent();
        notifyIcon1.ContextMenuStrip = contextMenuStrip1;
        this.showToolStripMenuItem.Click += showToolStripMenuItem_Click;
        this.exitToolStripMenuItem.Click += exitToolStripMenuItem_Click;
    }

    private bool allowVisible;     // ContextMenu's Show command used
    private bool allowClose;       // ContextMenu's Exit command used

    protected override void SetVisibleCore(bool value) {
        if (!allowVisible) {
            value = false;
            if (!this.IsHandleCreated) CreateHandle();
        }
        base.SetVisibleCore(value);
    }

    protected override void OnFormClosing(FormClosingEventArgs e) {
        if (!allowClose) {
            this.Hide();
            e.Cancel = true;
        }
        base.OnFormClosing(e);
    }

    private void showToolStripMenuItem_Click(object sender, EventArgs e) {
        allowVisible = true;
        Show();
    }

    private void exitToolStripMenuItem_Click(object sender, EventArgs e) {
        allowClose = true;
        Application.Exit();
    }
}

注意 Load 事件的一个问题,它在主窗体首次显示之前不会触发。因此,请务必在表单的构造函数中进行初始化,而不是在 Load 事件处理程序中。

The right way to do this is to prevent the form from getting visible in the first place. That requires overriding SetVisibleCore(). Let's assume a context menu for the NotifyIcon with a Show and Exit command. You can implement it like this:

public partial class Form1 : Form {
    public Form1() {
        InitializeComponent();
        notifyIcon1.ContextMenuStrip = contextMenuStrip1;
        this.showToolStripMenuItem.Click += showToolStripMenuItem_Click;
        this.exitToolStripMenuItem.Click += exitToolStripMenuItem_Click;
    }

    private bool allowVisible;     // ContextMenu's Show command used
    private bool allowClose;       // ContextMenu's Exit command used

    protected override void SetVisibleCore(bool value) {
        if (!allowVisible) {
            value = false;
            if (!this.IsHandleCreated) CreateHandle();
        }
        base.SetVisibleCore(value);
    }

    protected override void OnFormClosing(FormClosingEventArgs e) {
        if (!allowClose) {
            this.Hide();
            e.Cancel = true;
        }
        base.OnFormClosing(e);
    }

    private void showToolStripMenuItem_Click(object sender, EventArgs e) {
        allowVisible = true;
        Show();
    }

    private void exitToolStripMenuItem_Click(object sender, EventArgs e) {
        allowClose = true;
        Application.Exit();
    }
}

Note a wrinkle with the Load event, it won't fire until the main form is first shown. So be sure to do initialization in the form's constructor, not the Load event handler.

花之痕靓丽 2024-08-18 06:26:10

我正在阅读所有答案并看到黑客和黑魔法......(没有冒犯,伙计们)

不需要黑客。您甚至不必设置“ShowInTaskbar = false”和其他内容。只需执行以下操作:

    //"Form Shown" event handler
    private void Form_Shown(object sender, EventArgs e)
    {
        //to minimize window
        this.WindowState = FormWindowState.Minimized;

        //to hide from taskbar
        this.Hide();
    }

注意:我强烈建议不要触摸“ShowInTaskbar”属性。例如,如果您的应用程序注册了系统范围的热键或其他类似的东西(挂钩等) - 设置 ShowInTaskBar=false 并最小化您的应用程序将阻止 Windows 向您的窗口发送一些消息...并且您的挂钩/热键/等将停止工作。

I'm reading all the answers and see hacks and black magic... (no offense, mates)

No hacks needed. You don't even have to set "ShowInTaskbar=false" and other stuff. Just do this:

    //"Form Shown" event handler
    private void Form_Shown(object sender, EventArgs e)
    {
        //to minimize window
        this.WindowState = FormWindowState.Minimized;

        //to hide from taskbar
        this.Hide();
    }

NOTE: I strongly recommend NOT TOUCHING the "ShowInTaskbar" property. For example, if your application registers system-wide hotkeys or other similar stuff (hooks, etc) - setting ShowInTaskBar=false and minimizing your app will prevent Windows from sending some messages to your window... And your hooks/hotkeys/etc will stop working.

眼睛会笑 2024-08-18 06:26:10

构造函数中,删除这两行:

this.Visible = false;
this.ShowInTaskbar = false;

并在InitializeComponent();后面添加:

this.WindowState = FormWindowState.Minimized;

在设计器中,将ShowInTaskbar设置为false & FormWindowState 更改为 Normal

编辑:
如果您在加载事件中发布相同的内容,窗口确实会最小化,但在桌面上仍然显示最小化。我认为这是一个错误。

In the constructor, remove these two lines:

this.Visible = false;
this.ShowInTaskbar = false;

and add after InitializeComponent();:

this.WindowState = FormWindowState.Minimized;

In designer, set ShowInTaskbar to false & FormWindowState to Normal.

EDIT:
If you post the same in Load event, the window does get minimized but still shows minimized on the desktop. I think this is a bug.

妄断弥空 2024-08-18 06:26:10

当最小化应用程序并且您想要在 Alt+Tab 中隐藏它时:

当您将边框样式设置为工具窗口时,您还需要设置不透明度以阻止标题栏显示在“开始”菜单附近。

最小化事件时:

this.Visible = false;
this.Opacity = 0;
this.FormBorderStyle = FormBorderStyle.FixedToolWindow;
this.ShowInTaskbar = false;

标准化事件时:

this.Visible = true;
this.Opacity = 100;
this.FormBorderStyle = FormBorderStyle.FixedSingle; //or whatever it was previously set to
this.ShowInTaskbar = true;

When minimizing an application and you want to hide it from Alt+Tab:

You also need to set the Opacity to stop the titlebar showing near the Start Menu when you set the Border Style to a Tool Window.

On Minimize Event:

this.Visible = false;
this.Opacity = 0;
this.FormBorderStyle = FormBorderStyle.FixedToolWindow;
this.ShowInTaskbar = false;

On Normalize Event:

this.Visible = true;
this.Opacity = 100;
this.FormBorderStyle = FormBorderStyle.FixedSingle; //or whatever it was previously set to
this.ShowInTaskbar = true;
流殇 2024-08-18 06:26:10

将以下代码从 Form 的构造函数移至 Form_Main_Load()。在 Form_Resize() 时对 Notification_Icon 进行相同的设置

// Hide the Form to System Tray
this.WindowState = FormWindowState.Minimized;

Move the following code from the Form's constructor to Form_Main_Load(). With the same setup on Notification_Icon when Form_Resize().

// Hide the Form to System Tray
this.WindowState = FormWindowState.Minimized;
没有你我更好 2024-08-18 06:26:10

这个“快速而肮脏的修复”对我有用:

$form1.FormBorderStyle = "fixedtoolwindow"
$form1.top = -1000000
$form1.Left = -1000000
$form1.Width = 10
$form1.Height = 10
$form1.WindowState = "normal"
$form1.ShowInTaskbar = $False
$form1.Opacity = 0
$form1.Hide()

希望它对其他人有帮助......

This "quick and dirty fix" worked for me:

$form1.FormBorderStyle = "fixedtoolwindow"
$form1.top = -1000000
$form1.Left = -1000000
$form1.Width = 10
$form1.Height = 10
$form1.WindowState = "normal"
$form1.ShowInTaskbar = $False
$form1.Opacity = 0
$form1.Hide()

Hope it helps someone else...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文