Josef Van Zyl
Josef Van Zyl

Reputation: 925

Create an instance of app for each screen

I want my WinForms application to create an instance of itself for each screen and display on that screen. I have the following code:

Main form:

class MainForm
{
    public MainForm()
    {        
        string[] args = Environment.GetCommandLineArgs();

        foreach (string arg in args)
        {
          if (arg == "TakeOverAllScreens") { TakeOverAllScreens(); }
          if (arg.StartsWith("Screen|"))
             {
               string[] s;
               s = arg.Split('|');
               int xPos , yPos, screenNum ;
               int.TryParse(s[1], out xPos);
               int.TryParse(s[2], out yPos);
               int.TryParse(s[3], out screenNum);
               Screen[] sc;
               sc = Screen.AllScreens;
               this.Left = sc[screenNum].Bounds.Width;
               this.Top = sc[screenNum].Bounds.Height;
               this.StartPosition = FormStartPosition.Manual;
             }
        }

        InitializeComponent();
    }

    private void MainForm_Load(object sender, EventArgs e)
    {
        this.TopMost = true;
        this.FormBorderStyle = FormBorderStyle.None;
        this.WindowState = FormWindowState.Maximized;
    }
}

TakeOverAllScreens form:

private void TakeOverAllScreens()
{
    int i = 0;
    foreach (Screen s in Screen.AllScreens)
    {
        if (s != Screen.PrimaryScreen)
        {
            i++;
            Process.Start(Application.ExecutablePath, "Screen|" + s.Bounds.X + "|" + s.Bounds.Y+"|" + i);
        }
    }
}

My application does create a new instance for every screen, however it only displays on my main screen and does not display on the other screens.

Upvotes: 1

Views: 171

Answers (1)

Damien_The_Unbeliever
Damien_The_Unbeliever

Reputation: 239764

This looks suspect:

int.TryParse(s[1], out xPos);
int.TryParse(s[2], out yPos);
int.TryParse(s[3], out screenNum);
Screen[] sc;
sc = Screen.AllScreens;
this.Left = sc[screenNum].Bounds.Width;
this.Top = sc[screenNum].Bounds.Height;

You pass x and y values across on the command line, and then ignore them and use the width and height of the screen to set your x/y values. If all of the screens are the same resolution, and arranged horizontally or vertically, it's likely that all of these windows are positioned below (or to the right of) any visible portions of the screen.

I also can't find any guarantee that Screen.AllScreens will always return the screens in the same order, so the screenNum value may be referencing a different screen.


I'd also prefer to see this code appearing after the call to InitializeComponents rather than before, so you know that any designer set properties will be overridden by your code, rather than vice versa.


So, my code is:

public MainForm()
{   
    InitializeComponent();

    string[] args = Environment.GetCommandLineArgs();

    foreach (string arg in args)
    {
        if (arg == "TakeOverAllScreens") { TakeOverAllScreens(); }
        if (arg.StartsWith("Screen|"))
        {
            string[] s;
            s = arg.Split('|');
            int xPos, yPos, screenNum;
            int.TryParse(s[1], out xPos);
            int.TryParse(s[2], out yPos);
            this.Left = xPos;
            this.Top = yPos;
            this.StartPosition = FormStartPosition.Manual;
        }
    }
}

And:

private void TakeOverAllScreens()
{
    foreach (Screen s in Screen.AllScreens)
    {
        if (s != Screen.PrimaryScreen)
        {
            Process.Start(Application.ExecutablePath, "Screen|" + s.Bounds.X + "|" + s.Bounds.Y);
        }
    }
}

Of course, the TryParse calls are pointless and can be replaced by Parse, if you're just going to ignore the return value.

Upvotes: 1

Related Questions