有什么办法在C#中创建一个隐藏的主窗口?

时间:2009-03-25 23:12:30

标签: c# winforms

我只想要一个带有隐藏主窗口的c#应用程序,它将处理并响应窗口消息。

我可以在不显示的情况下创建表单,然后可以调用Application.Run()而不传入表单,但是如何将创建的表单挂钩到消息循环中呢?

还有其他方法可以解决这个问题吗?

提前感谢任何提示!

12 个答案:

答案 0 :(得分:17)

出色!那个链接指向了我正确的方向。这似乎有效:

        Form f = new Form1();
        f.FormBorderStyle = FormBorderStyle.FixedToolWindow;
        f.ShowInTaskbar = false;
        f.StartPosition = FormStartPosition.Manual;
        f.Location = new System.Drawing.Point(-2000, -2000);
        f.Size = new System.Drawing.Size(1, 1);
        Application.Run(f);

为了防止它显示在Alt-Tab中,您需要它作为工具窗口。不幸的是,这可以防止它最小化。但是将开始位置设置为手动并将其定位在屏幕外就行了!

答案 1 :(得分:17)

在重写VC ++ TaskTray应用程序的过程中,在C#.NET中,我发现以下方法真正可行以实现以下目的。

  1. 启动时没有初始形式
  2. 根据需要运行可与Invoke / BeginInvoke一起使用的消息循环 IsWindowHandle 为真
  3. 我遵循的步骤:

    1. 在Application.Run()中使用ApplicationContext而不是表单。有关我使用的示例,请参阅http://www.codeproject.com/Articles/18683/Creating-a-Tasktray-Application
    2. 在GUI Designer中将Form的 ShowInTaskbar 属性设置为true。 (这似乎适得其反,但确实有效)
    3. 将表单类设置可见 ShowInTaskbar 中的 OnLoad()方法覆盖为false,如下所示。
    4. protected override void OnLoad(EventArgs e)
          {
              Visible = false; 
              ShowInTaskbar = false; 
              base.OnLoad(e);
          }
      

答案 2 :(得分:13)

我知道这是一个老问题,但它在谷歌排名很好,所以无论如何我都会提供我的解决方案。

我做了两件事:

private void Form_Load(object sender, EventArgs e)
{
    Opacity = 0;
}

private void Form_Shown(object sender, EventArgs e)
{
    Visible = false;
    Opacity = 100;
}

答案 3 :(得分:8)

最好的方法是在构造函数中使用以下1-2行:

this.WindowState = FormWindowState.Minimized;
this.ShowInTaskbar = false; // This is optional

您甚至可以在VS Property窗口中看到Minimized属性。

答案 4 :(得分:5)

您可以创建一个继承自System.Windows.Forms.NativeWindow(提供基本消息循环功能)的类,并在其构造函数中引用Handle属性以创建其句柄并将其挂钩到消息循环中。致电Application.Run后,您就可以处理来自该消息的消息。

答案 5 :(得分:4)

我解决了这个问题:

[STAThread]
static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Main main = new Main();
    Application.Run();
    //Application.Run(new Main());
}

此代码驻留在Program.cs文件中,您可以看到原始的Application.Run方法调用已注释掉。我只是创建一个Main类对象(我的主窗体类名为Main)并启动没有任何参数的应用程序消息循环。这将启动应用程序,初始化任何表单组件,但不显示表单。

注意:你必须有一些方法来显示你的窗口(如系统托盘图标,热键或计时器或你可能喜欢的任何东西)。

答案 6 :(得分:2)

public partial class Form1 : Form
{
    private bool _isApplicationRun;

    public Form1(bool applicationRun)
    {
        InitializeComponent();
        _isApplicationRun = applicationRun;
    }

    protected override void SetVisibleCore(bool value)
    {
        if (_isApplicationRun)
        {
            _isApplicationRun = false;

            base.SetVisibleCore(false);
            return;
        }

        base.SetVisibleCore(value);
    }
}

static class Program
{

    [STAThread]
    static void Main()
    {

        Application.Run(new Form1(true));
    }
}

答案 7 :(得分:1)

为什么不能在致电Application.Run时传递表单?鉴于它显然是一个阻止调用,您希望在什么事件中显示该表单?只需拨打form.Show()即可。

答案 8 :(得分:1)

使用Kami的答案作为灵感,我创造了一个更完整的概念。如果您使用此解决方案,请不要显示隐藏的窗口。如果这样做,用户可能会将其关闭,然后您无法以有序的方式控制应用程序退出。此方法可用于管理Timer,NotifyIcon或任何其他快乐生活在隐形表单上的组件。

using System;
using System.Windows.Forms;

namespace SimpleHiddenWinform
{
    internal class HiddenForm : Form
    {
        private Timer _timer;
        private ApplicationContext _ctx;

        public HiddenForm(ApplicationContext ctx)
        {
            _ctx = ctx;
            _timer = new Timer()
            {
                Interval = 5000, //5 second delay
                Enabled = true
            };
            _timer.Tick += new EventHandler(_timer_Tick);
        }

        void _timer_Tick(object sender, EventArgs e)
        {
            //tell the main message loop to quit
            _ctx.ExitThread();
        }
    }

    static class Program
    {
        [STAThread]
        static void Main()
        {
            var ctx = new ApplicationContext();
            var frmHidden = new HiddenForm(ctx);
            //pass the application context, not the form
            Application.Run(ctx);
        }
    }
}

答案 9 :(得分:0)

Form1 f1=new Form1();
f1.WindowState = FormWindowState.Minimized;
f1.ShowInTaskbar = false;

答案 10 :(得分:-1)

在Form1代码文件中

添加this.Visible = false;到构造函数。

这将隐藏窗口,但在隐藏之前它会闪烁一秒。或者,您可以编写自己的Application.Run命令。

了解更多信息http://social.msdn.microsoft.com/forums/en-US/winforms/thread/dece45c8-9076-497e-9414-8cd9b34f572f/

您也可以将this.ShowInTaskbar设置为false。

答案 11 :(得分:-1)

您应该查看创建“服务”,因为这是一个没有表单的应用程序。 见http://support.microsoft.com/kb/816169