4

一段时间以来,我一直试图让我的 WPF 应用程序跨越多个监视器,并且几乎可以正常工作。

当我设置以下行时,问题似乎出现了:

win1.WindowState = WindowState.Maximized

这会导致应用程序仅跨越主屏幕。

我的代码如下:

public partial class App : Application
{
    private void Application_Startup(object sender, StartupEventArgs e)
    {
        Window1 win1 = new Window1();
        win1.WindowStartupLocation = WindowStartupLocation.Manual;
        win1.Width = 2560;
        win1.Height = 1024;
        win1.Left = 0;
        win1.Top = 0;
        win1.Topmost = true;
        win1.Background = new SolidColorBrush(Colors.Black);
        win1.WindowStyle = WindowStyle.None;
        win1.Show();
        win1.Focus();
    }
}

在窗口 1 内:

public partial class Window1 : Window
{
    public Window1()
    {

    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        WindowState = WindowState.Maximized;
    }
}

此示例有效,但窗口未最大化,应用程序边框仍然可见。

在 Application_Startup 中包含最大化的减速使监视器最大化到主监视器。

为什么是这样?

4

2 回答 2

12

首先请注意,“最大化”的概念与单个监视器相关联,因此您不能真正在多个监视器上拥有最大化的窗口。当然,在 WPF 中,您可以创建自己的窗口框架并在其中绘制任何您喜欢的内容,因此如果您愿意,您当然可以让用户认为窗口已最大化并跨越多个屏幕。

另请注意,仅在两种情况下,可以使用单个矩形窗口跨越两个监视器:

  1. 两台显示器具有相同的高度并配置为并排,或
  2. 两台显示器宽度相同,配置为上下。

否则,您将需要使用两个单独的窗口来覆盖两个显示器的整个表面,或者使用一个包含任何显示器未覆盖的区域的大窗口。

好的,以下是获取定位窗口所需信息的方法:

WPF 本身不提供询问显示器数量、分辨率或相对位置的方法。幸运的是,我们可以使用 [DllImport] 直接调用 Win32。要获得显示器分辨率和布局,只需:

  1. 将 MONITORINFO 结构声明为 C# 中的结构
  2. 为在 User32.dll 中找到的 EnumDisplayMonitors 和 GetMonitorInfo 声明 DllImports
  3. 编写一个调用 EnumDisplayMonitors 并传递一个委托的方法,该委托获取监视器信息并在列表中返回它。

这是基本思想:

List<MONITORINFO> GetAllMonitorInfo()
{
  var result = List<MONITORINFO>();
  EnumDisplayMonitors(null, null,
    (hMonitor, hdcMonitor, lprcMonitor, dwData) =>
    {
      var info = new MONITORINFO { cbSize = Marshall.Sizeof(typeof(MONITORINFO)) };
      GetMonitorInfo(hMonitor, ref info);
      result.Add(info);
    }, null);
  return result;
}

获得监视器坐标后,使用您选择的算法来选择要创建的窗口数量以及每个窗口所需的坐标。然后使用明确的大小和位置创建窗口。

请注意,您可能希望使用 rcWork 而不是 rcMonitor,这样您就不会覆盖开始菜单等。

另请注意,在许多情况下,返回的某些坐标将为负数,例如,如果辅助监视器位于主监视器的左侧。这不是问题:只需使用给定的坐标,您的窗口就会出现在正确的位置。

于 2009-12-24T02:08:33.313 回答
-1

如果您始终可以假设您的辅助监视器与主监视器具有相同的分辨率,则可以实现如下所示:

// Use this is you are concerned about the taskbar height
Rect workArea = SystemParameters.WorkArea;
this.Width = SystemParameters.PrimaryScreenWidth * 2;
this.Height = workArea.Bottom;
this.Left = 0;
this.Top = 0;

或者:

// Use this is you don't care about the taskbar height
this.Width = SystemParameters.PrimaryScreenWidth * 2;
this.Height = SystemParameters.PrimaryScreenHeight;
this.Left = 0;
this.Top = 0;
于 2009-12-23T21:11:32.387 回答