启动应用程序并将其发送到第二个监视器?

2024-05-15 20:58:49 发布

您现在位置:Python中文网/ 问答频道 /正文

有没有办法在另一个屏幕上通过进程启动/使用午餐程序?

有人问这个问题,但没有人回答。

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


Tags: 程序应用程序表单屏幕进程午餐办法
3条回答

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

  • 启动进程。

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

  • 使用^{}更改窗口的位置。

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

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

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

  • 使用^{}更改窗口的位置。

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

首先从第二个监视器的区域出来,使用如下方法:

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

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

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

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

但基本的逻辑是一样的:

  1. 找到要操作的Windows句柄。您可以在前面提到的一般情况下使用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

相关问题 更多 >