1

我希望我的 WinForms 应用程序为每个屏幕创建一个自身的实例并在该屏幕上显示。我有以下代码:

主要形式:

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 表单:

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);
        }
    }
}

我的应用程序确实为每个屏幕创建了一个新实例,但是它只显示在我的主屏幕上,而不会显示在其他屏幕上。

4

1 回答 1

1

这看起来很可疑:

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;

您在命令行上传递x和值,然后忽略它们并使用屏幕的宽度高度来设置您的 x/y 值。如果所有屏幕的分辨率相同,并且水平或垂直排列,则所有这些窗口很可能都位于屏幕任何可见部分的下方(或右侧)。y

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.

于 2012-06-22T08:06:21.410 回答