tags:

views:

2677

answers:

7

Hi

I followed the commonly-linked tip for reducing an application to the system tray : http://www.developer.com/net/csharp/article.php/3336751 Now it works, but there is still a problem : my application is shown when it starts ; I want it to start directly in the systray. I tried to minimize and hide it in the Load event, but it does nothing.

Edit : I could, as a poster suggested, modify the shortcut properties, but I'd rather use code : I don't have complete control over every computer the soft is installed on.

I don't want to remove it completely from everywhere except the systray, I just want it to start minimized.

Any ideas ?

Thanks

+1  A: 

If you are using a NotifyIcon, try changing ShowInTaskbar to false.

To remove it from the Alt+Tab screen, try changing your window border style; I believe some of the tool-window styles don't appear...

something like:

using System;
using System.Windows.Forms;
class MyForm : Form
{
    NotifyIcon sysTray;

    MyForm()
    {
        sysTray = new NotifyIcon();
        sysTray.Icon = System.Drawing.SystemIcons.Asterisk;
        sysTray.Visible = true;
        sysTray.Text = "Hi there";
        sysTray.MouseClick += delegate { MessageBox.Show("Boo!"); };

        ShowInTaskbar = false;
        FormBorderStyle = FormBorderStyle.SizableToolWindow;
        Opacity = 0;
        WindowState = FormWindowState.Minimized;
    }

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.Run(new MyForm());
    }
}

If it still appears in the Alt+Tab, you can change the window styles through p/invoke (a bit hackier):

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    IntPtr handle = this.Handle;
    int currentStyle = GetWindowLong(handle, GWL_EXSTYLE);
    SetWindowLong(handle, GWL_EXSTYLE, currentStyle | WS_EX_TOOLWINDOW);
}
private const int GWL_EXSTYLE = -20, WS_EX_TOOLWINDOW = 0x00000080;
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr window, int index, int value);
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern int GetWindowLong(IntPtr window, int index);
Marc Gravell
+1  A: 
xan
+5  A: 

this is how you do it

static class Program
{
    [STAThread]
    static void Main()
    {
        NotifyIcon icon = new NotifyIcon();
        icon.Icon = System.Drawing.SystemIcons.Application;
        icon.Click += delegate { MessageBox.Show("Bye!"); icon.Visible = false; Application.Exit(); };
        icon.Visible = true;
        Application.Run();
    }
}
lubos hasko
+7  A: 

In your main program you probably have a line of the form:

Application.Run(new Form1());

This will force the form to be shown. You will need to create the form but not pass it to Application.Run:

Form1 form = new Form1();
Application.Run();

Note that the program will now not terminate until you call Application.ExitThread(). It's best to do this from a handler for the FormClosed event.

private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
    Application.ExitThread();
}
Sunlight
A: 

Since this was tagged with vb.net, here's what I did in a Windows Service and Controller app I just finished, Add a code module to the project, Setup the NotifyIcon and it's associated Context menu in Sub Main(), and then set the application's Startup Object to the Sub Main() instead of the Form.

Public mobNotifyIcon As NotifyIcon
Public WithEvents mobContextMenu As ContextMenu

Public Sub Main()

    mobContextMenu = New ContextMenu
    SetupMenu()
    mobNotifyIcon = New NotifyIcon()
    With mobNotifyIcon
        .Icon = My.Resources.NotifyIcon
        .ContextMenu = mobContextMenu
        .BalloonTipText = String.Concat("Monitor the EDS Transfer Service", vbCrLf, "Right click icon for menu")
        .BalloonTipIcon = ToolTipIcon.Info
        .BalloonTipTitle = "EDS Transfer Monitor"
        .Text = "EDS Transfer Service Monitor"
        AddHandler .MouseClick, AddressOf showBalloon
        .Visible = True
    End With
    Application.Run()
End Sub

Private Sub SetupMenu()
    With mobContextMenu

        .MenuItems.Add(New MenuItem("Configure", New EventHandler(AddressOf Config)))
        .MenuItems.Add("-")
        .MenuItems.Add(New MenuItem("Start", New EventHandler(AddressOf StartService)))
        .MenuItems.Add(New MenuItem("Stop", New EventHandler(AddressOf StopService)))
        .MenuItems.Add("-")
        .MenuItems.Add(New MenuItem("Exit", New EventHandler(AddressOf ExitController)))
    End With
    GetServiceStatus()
End Sub

In the Config(), I create an instance of my form and display it.

Private Sub Config(ByVal sender As Object, ByVal e As EventArgs)
    Using cs As New ConfigureService
        cs.Show()
    End Using

End Sub
rjrapson
A: 

Here you go:

Create 2 classes, 1 which inherits from ApplicationContext. The other only contains a Main routine. I've made an example that has a form and a notifyicon that when double clicked brings up the form and back again.

Remember to set "Sub Main" as your startup object in My Project settings and point to a real *.ico file instead of f:\TP.ico .. :)

Code should of course be stuffed with proper error handling code.

Class1:

Imports System.threading 
Imports System.Runtime.InteropServices 
Imports System.Windows.Forms


Public Class Class1

    <System.STAThread()> _
        Public Shared Sub Main()

        Try
            System.Windows.Forms.Application.EnableVisualStyles()
            System.Windows.Forms.Application.DoEvents()
            System.Windows.Forms.Application.Run(New Class2)
        Catch invEx As Exception

            Application.Exit()

        End Try


    End Sub 'Main End Class

Class2:

Imports System.Windows.Forms  
Imports System.drawing

Public Class Class2
    Inherits System.Windows.Forms.ApplicationContext

    Private WithEvents f As New System.Windows.Forms.Form
    Private WithEvents nf As New System.Windows.Forms.NotifyIcon

    Public Sub New()

        f.Size = New Drawing.Size(50, 50)
        f.StartPosition = FormStartPosition.CenterScreen
        f.WindowState = Windows.Forms.FormWindowState.Minimized
        f.ShowInTaskbar = False
        nf.Visible = True
        nf.Icon = New Icon("f:\TP.ico")
    End Sub


    Private Sub nf_DoubleClick(ByVal sender As Object, ByVal e As EventArgs) Handles nf.DoubleClick
        If f.WindowState <> Windows.Forms.FormWindowState.Minimized Then
            f.WindowState = Windows.Forms.FormWindowState.Minimized
            f.Hide()
        Else
            f.WindowState = Windows.Forms.FormWindowState.Normal
            f.Show()
        End If
    End Sub

    Private Sub f_FormClosed(ByVal sender As Object, ByVal e As FormClosedEventArgs) Handles f.FormClosed
        Application.Exit()
    End Sub  End Class
A: 

This shows you how to control startup as minimized or normal as well as much more with NotifyIcon.

More here: http://code.msdn.microsoft.com/TheNotifyIconExample