winform获取屏幕信息
因为WPF 和 Windows Forms 可以在同一个 .NET 应用程序中互操作,我们可以通过using System.Windows.Forms的方式来获取屏幕信息
- 获取有几个显示器
Screen.AllScreens.Length
Screen.AllScreens.Count()
- 获取屏幕
Screen targetScreen = Screen.AllScreens[0];
Console.WriteLine(targetScreen.Bounds);
Screen targetScreen1 = Screen.AllScreens[1];
Console.WriteLine(targetScreen1.Bounds);
- 获取主屏幕
// Primary是否为主屏幕
Console.WriteLine(targetScreen.Primary);
Console.WriteLine(targetScreen1.Primary);
- 获取bound
Rectangle bounds = Screen.AllScreens[0].Bounds; 第一个显示器的bounds
- 移动鼠标
// 这两个都是设置鼠标的位置
//Cursor.Position 是.NET Framework中System.Windows.Forms.Cursor类的一个静态属性,用于获取或设置鼠标指针的屏幕位置。
//与SetCursorPos不同,Cursor.Position是直接在C#中可用的,不需要P/Invoke。
Cursor.Position = new Point(100, 100);
//SetCursorPos 是一个Windows API函数,用于设置鼠标指针的屏幕位置。
//它不是C#语言本身的一部分,而是Windows操作系统提供的一个函数,可以通过P/Invoke(平台调用)技术在C#中调用。
SetCursorPos(3000, 100);
注意:如果你的项目和我一样,创建的是纯WPF应用程序(而非“WPF应用(.netframework)”),那么可能会无法引用System.Windows.Forms
image.png
解决方案:需要在WPF 项目的 .csproj 文件中添加一些配置来启用对 Windows Forms 的支持。
<UseWindowsForms>true</UseWindowsForms>
也可以鼠标左键双击项目,在vs中更改
image.png
然后重新打开项目就开了,我们会看到分析器中多了两个引用
image.png
WPF获取屏幕信息:
在纯WPF项目中,如果直接引入System.Windows.Forms可能会导致一些不兼容性和控件冲突。但是,获取屏幕信息并不一定要依赖于System.Windows.Forms。WPF 提供了自己的方式来处理多屏幕环境。
- 获取主屏幕的工作区大小
使用 SystemParameters.PrimaryScreenWidth 和 SystemParameters.PrimaryScreenHeight 可以获取主屏幕的工作区宽度和高度(不包括任务栏等)。但是,这不会给你所有屏幕的信息。 - 获取当前窗口的屏幕位置:
使用 WindowInteropHelper 和 PresentationSource 可以获取当前 WPF 窗口在屏幕上的位置,但这同样不会给你所有屏幕的信息。 - 获取有几个显示器:
WPF 实际上是在 PresentationCore 程序集中封装了对多屏幕支持的,而这个程序集是 WPF 应用程序默认引用的。我们可以使用反射来访问这个隐藏的功能,或者更简单地,我们可以直接调用 Windows API,因为 WPF 底层也是这么做的。
using System;
using System.Runtime.InteropServices;
using System.Windows;
public class ScreenHelper
{
[DllImport("user32.dll")]
private static extern int GetSystemMetrics(int smIndex);
// SM_CMONITORS is not defined in .NET, so we use its value directly
private const int SM_CMONITORS = 80;
public static int GetScreenCount()
{
// Note: This will return the number of "logical" monitors, which may differ
// from the number of physical monitors if a multi-monitor setup involves
// mirroring or spanning displays.
return GetSystemMetrics(SM_CMONITORS);
}
}
// 在你的WPF应用程序中使用这个帮助类
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
int screenCount = ScreenHelper.GetScreenCount();
MessageBox.Show($"Number of screens: {screenCount}");
}
}
实战
假设我们有一个需求,需要在两个屏幕上展示不同的设计效果,这里我们假设两个屏幕分辨率都是1920*1080
-
第一种方式:采用一个window
image.png
如果不确定两个屏幕分辨率,则可以后台代码去修改
Rectangle bounds1 = Screen.AllScreens[0].Bounds;
Rectangle bounds2 = Screen.AllScreens[1].Bounds;
this.mainCanvas.Width = base.Width = bounds1.Width + bounds2.Width;
this.mainCanvas.Height = base.Height = ((bounds1.Height > bounds2.Height) ? bounds1.Height : bounds2.Height);
this.grid1.Width = bounds1.Width;
this.grid1.Height = bounds1.Height;
this.grid2.Width = bounds2.Width;
this.grid2.Height = bounds2.Height;
this.grid1.SetValue(Canvas.LeftProperty, 0.0);
this.grid2.SetValue(Canvas.LeftProperty, this.grid1.Width);
- 第二种方式:采用两个window
我们点击按钮,先展示第一个窗口
private void Button_Click(object sender, RoutedEventArgs e)
{
Window1 win1 = new Window1()
{
Width = 1920,
Height = 1080,
Top = 0,
Left = 0,
};
win1.Show();
}
在第一个窗口里我们再去展示第二个窗口,这样我们就只需要在第一个窗口上加关闭逻辑就可以了。
public partial class Window1 : Window
{
private Window2 win2;
public Window1()
{
InitializeComponent();
// 第二个显示器
win2 = new Window2()
{
Width = 1920,
Height = 1080,
Top = 0,
Left = 1920,
};
win2.Show();
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
win2?.Close();
}
}