Есть ли способ создать скрытое главное окно в C #? - PullRequest
20 голосов
/ 26 марта 2009

Мне просто нужно приложение на c # со скрытым главным окном, которое будет обрабатывать и отвечать на оконные сообщения.

Я могу создать форму, не показывая ее, а затем вызвать Application.Run (), не передавая форму, но как я могу подключить созданную форму к циклу сообщений?

Есть ли другой способ сделать это?

Заранее спасибо за любые советы!

Ответы [ 12 ]

17 голосов
/ 26 марта 2009

Отлично! Эта ссылка указала мне в правильном направлении. Это похоже на работу:

        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, оно должно быть окном инструментов. К сожалению, это препятствует тому, чтобы это начало было свернуто. Но установив начальную позицию на Ручную и расположив ее вне экрана, добьемся цели!

17 голосов
/ 16 января 2013

В процессе переписывания VC ++ TaskTray App в C # .NET я обнаружил, что следующий метод действительно работает для достижения следующих целей.

  1. При запуске не отображается начальная форма
  2. Запуск цикла сообщений, который при необходимости можно использовать с Invoke / BeginInvoke, если IsWindowHandle true

Шаги, за которыми я следовал:

  1. Использовал ApplicationContext в Application.Run () вместо формы. См. http://www.codeproject.com/Articles/18683/Creating-a-Tasktray-Application для примера, который я использовал.
  2. Установите для свойства ShowInTaskbar формы значение true в конструкторе графического интерфейса. (Это кажется контрпродуктивным, но это работает)
  3. Переопределите метод OnLoad () в настройках класса формы Visible и ShowInTaskbar на false, как показано ниже.
protected override void OnLoad(EventArgs e)
    {
        Visible = false; 
        ShowInTaskbar = false; 
        base.OnLoad(e);
    }
13 голосов
/ 06 февраля 2011

Я знаю, что это старый вопрос, но он хорошо зарекомендовал себя в Google, поэтому я все равно предоставлю свое решение.

Я делаю две вещи:

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

private void Form_Shown(object sender, EventArgs e)
{
    Visible = false;
    Opacity = 100;
}
8 голосов
/ 05 апреля 2009

Лучше всего использовать следующие 1-2 строки в конструкторе:

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

Вы даже можете установить свойство Minimized в окне свойств VS.

5 голосов
/ 26 марта 2009

Вы можете создать класс, унаследованный от System.Windows.Forms.NativeWindow (который обеспечивает базовую возможность цикла сообщений), и обратиться к свойству Handle в его конструкторе, чтобы создать его дескриптор и подключить его к циклу сообщений. Как только вы позвоните Application.Run, вы сможете обрабатывать сообщения от него.

4 голосов
/ 19 апреля 2010

Я решил проблему следующим образом:

[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) и запускаю цикл сообщений приложения без каких-либо параметров. Это запускает приложение, инициализирует любые компоненты формы, но не показывает форму.

Примечание: у вас должен быть какой-то метод для отображения вашего окна (например, значок в системном трее, горячая клавиша или таймер или все, что вам может понравиться).

2 голосов
/ 15 апреля 2009
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));
    }
}
1 голос
/ 06 июня 2010

Используя ответ Ками как вдохновение, я создал более полную концепцию. Если вы используете это решение, никогда не показывайте скрытое окно. Если вы это сделаете, пользователь может закрыть его, и тогда вы потеряете возможность упорядоченно управлять выходом из приложения. Этот подход можно использовать для управления 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);
        }
    }
}
1 голос
/ 26 марта 2009

Почему вы не можете просто передать форму, когда звоните Application.Run? Учитывая, что это явно блокирующий вызов, на каком событии вы хотите показать форму? Достаточно просто позвонить form.Show().

0 голосов
/ 09 марта 2017
Form1 f1=new Form1();
f1.WindowState = FormWindowState.Minimized;
f1.ShowInTaskbar = false;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...