【问题标题】:Launch an application and send it to second monitor?启动应用程序并将其发送到第二台显示器?
【发布时间】:2011-04-14 14:06:24
【问题描述】:

有什么方法可以在另一个屏幕中通过 Process 启动/启动程序?

有人问here,但没有答案。

注意:它不是我应用程序中的表单,我是在询问在另一个屏幕上运行外部程序!

【问题讨论】:

标签: c# monitor multiple-monitors


【解决方案1】:

由于窗口不是您的,您只能通过调用 Windows API 来移动它。你必须这样做:

  • 启动进程。

  • 使用FindWindow 检索窗口句柄。如果窗口尚不存在,则该进程尚未创建它;睡眠 500 毫秒,然后重试。 (但不要进入无限循环;如果在合理的超时后找不到窗口,请停止。)

  • 使用SetWindowPos改变窗口的位置。

如果不知道窗口的标题,就不能使用FindWindow。在这种情况下,

  • 启动进程并通过检索Process.Handle获取进程句柄。

  • 使用EnumWindows 检索所有窗口。对于每个窗口,使用GetWindowThreadProcessId 检查它是否属于您的进程。如果没有窗口属于您的进程,请等待并继续尝试。

  • 使用SetWindowPos改变窗口的位置。

当然,您可以使用Screen.AllScreens[n].WorkingArea 来检索您想要的屏幕的位置和大小,然后您可以相对于它定位窗口。

【讨论】:

    【解决方案2】:

    首先使用类似的方法从第二台显示器的区域中取出:

    Rectangle area = Screen.AllScreens[1].WorkingArea;
    

    使用 Windows API SetWindowPos 移动它,使用从另一个进程开始时获得的 Process.MainWindowHandle 作为句柄。

    【讨论】:

      【解决方案3】:

      Timwi 提供了一个非常有用的提示,因此我决定创建一个 powershell 脚本,调用具有这些函数的库以便于使用,并分享解决方案。

      我需要在启动时运行多个 Chrome 窗口,而 GitHub 上的解决方案正是针对这个问题(相关问题:https://superuser.com/a/901790/111424)。

      但底层逻辑是一样的:

      1. 找到要操作的 Windows 句柄。您可以在 Timwi 提到的一般情况下使用 FindWindow 或 EnumWindows。但是,如果您的流程很简单并且只有一个主窗口,那就是:

        var hndl = proc.MainWindowHandle
        
      2. 有了句柄,你就可以使用下面的函数了。您只需要提供显示编号(从 1 开始)和句柄:

        public static bool MoveToMonitor(IntPtr windowHandle, int monitor)
        {
            monitor = monitor - 1;
            return WinApi.SetWindowPos(windowHandle, IntPtr.Zero, Screen.AllScreens[monitor].WorkingArea.Left,
                Screen.AllScreens[monitor].WorkingArea.Top, 1000, 800, SetWindowPosFlags.SWP_NOZORDER | SetWindowPosFlags.SWP_NOREDRAW);
        }
        

      您可以在 http://www.pinvoke.net/ 上找到所有枚举和函数导入,或者直接在 GitHub 上复制我的代码:https://github.com/alex-tomin/Tomin.Tools.KioskMode

      【讨论】:

        【解决方案4】:

        您需要启动进程,获取进程主窗口并使用 API 调用(如 SetWindowPos())将窗口移动到所需的屏幕。

        【讨论】:

          【解决方案5】:

          尝试把这段代码放在form_load方法中:

          this.setdesktoplocation(int x, int y);
          this.windowstate = formwindowstate.maximized;
          

          x 的值必须大于主屏幕的宽度。例如,如果您的主屏幕的分辨率为 1366 x 786 像素,您应该为 x 提供至少 1368 或更高的值。

          它对我有用。但这仅用于调试目的。毕竟,您必须在应用完成后在主监视器中运行它。

          【讨论】:

            【解决方案6】:

            如果您没有最大化您的窗口,但在您关闭它时让它未最大化,则下次打开应用程序时,它将显示在上次打开的监视器上。

            如果应用程序/窗口在您关闭时最大化,并且如果您下次再次打开它,它将显示在您的主显示器上。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2010-09-17
              • 2016-10-08
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多