Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 屏幕分辨率与屏幕不匹配。边界_C#_Windows 8.1_Resolution_Dpi - Fatal编程技术网

C# 屏幕分辨率与屏幕不匹配。边界

C# 屏幕分辨率与屏幕不匹配。边界,c#,windows-8.1,resolution,dpi,C#,Windows 8.1,Resolution,Dpi,我发现通过控制面板设置的分辨率和我的宽屏笔记本电脑的Screen.Bounds输出之间有一个有趣的差别。屏幕是15.5英寸,通过控制面板设置的分辨率是1920x1080。但是当我运行这样的代码时 Screen[] screens = Screen.AllScreens; foreach (Screen scr in screens) { Console.WriteLine("Width: " + scr.Bounds.Width + ", Height: " + scr.Bounds.W

我发现通过控制面板设置的分辨率和我的宽屏笔记本电脑的Screen.Bounds输出之间有一个有趣的差别。屏幕是15.5英寸,通过控制面板设置的分辨率是1920x1080。但是当我运行这样的代码时

Screen[] screens = Screen.AllScreens;
foreach (Screen scr in screens)
{
    Console.WriteLine("Width: " + scr.Bounds.Width + ", Height: " + scr.Bounds.Width);
}
输出显示我的分辨率是1536x864。我已经做了一些环视,我认为它可能与DPI有关,当我看我的显示设置时,滑块(我在Windows 8.1上)在中间,并且复选框表示“让我为所有的显示器选择一个缩放级别”。“这是不受限制的。我运行了这个小代码来获取当前的DPI设置

float dpiX, dpiY;
Graphics graphics = new System.Windows.Forms.Form().CreateGraphics();
Console.WriteLine("DPI: " + graphics.DpiX);

返回的DPI是96.0,据我所知,这是100%DPI设置(因此没有放大或其他名称)。我觉得奇怪的是,屏幕返回的边界正好是我实际分辨率的80%,这会让我认为我的DPI设置为100(或125%),但事实并非如此。我的笔记本电脑屏幕上只有这个问题,因为我的辅助显示器的分辨率与控制面板上的分辨率相等。这是因为我的DPI设置没有设置为使显示器相互独立(选中该复选框)?作为一点背景,我正在编写一个工具,它从reddit获取当前屏幕和图片,并将它们独立地安装到屏幕上,因此无论我有什么解决方案,它都必须正确获得每个显示的分辨率。

我相信您必须通知操作系统您的应用程序支持DPI。否则,操作系统会假装一切正常,导致您观察到的行为——操作系统会处理大小调整

你可以在这里找到一些关于编写支持DPI的应用程序的信息——当然,你应该确保你的应用程序实际上是支持DPI的——如果不是,你最好还是使用默认设置。虽然没有那么好,但至少它会起作用


Windows 8.1带来的主要区别在于,您可以在不同的监视器上使用不同的DPI,并且可以查询监视器DPI API。NET(尤其是WPF)默认情况下自动处理DPI感知,但仅基于系统DPI。如果您的显示器具有不同的DPI设置,它将表现为非DPI感知(更准确地说,系统DPI感知,但最终结果是您的应用程序图形将由Windows虚拟化)。我希望,如果您断开第二个显示器的连接,您的应用程序将在您的唯一显示器上按预期运行(至少在手动设置DPI后,无论其值如何)。

对于屏幕截图工具,我也遇到了同样的问题。 我找到了解决办法,它对我很有效

private enum ProcessDPIAwareness
{
  ProcessDPIUnaware = 0,
  ProcessSystemDPIAware = 1,
  ProcessPerMonitorDPIAware = 2
}

[DllImport("shcore.dll")]
private static extern int SetProcessDpiAwareness(ProcessDPIAwareness value);

private static void SetDpiAwareness()
{
  try
  {
    if (Environment.OSVersion.Version.Major >= 6)
    {
      SetProcessDpiAwareness(ProcessDPIAwareness.ProcessPerMonitorDPIAware);
    }
  }
  catch (EntryPointNotFoundException)//this exception occures if OS does not implement this API, just ignore it.
  {
  }
}
在调用函数以获得系统分辨率等之前,应该调用SetDpiAwareness()方法。 此外,如果您的应用程序中现在有一些UI,则您有责任在屏幕中以高DPI扩展UI


希望这能有所帮助。

我假设
scr.Bounds..Primary
在您的第一个代码示例中应该是
scr.Bounds.Height
?如果“让我为所有显示选择一个缩放级别”未选中,那么您肯定为每个屏幕设置了不同的DPI吗?@StevenRands修复了该示例,我认为情况就是这样,但是,如果未选中该框,两个屏幕的DPI仍为96.0。我是否在获取DPI的方式上做错了什么?本身并没有错,只是
Graphics
实例的DPI可能默认为主屏幕的DPI。您是否使用Windows 8.1?有一个API可能有用。有趣的是,我可以从.NET中调用它吗?或者它必须是C++的吗?谢谢,这很有帮助。您知道是否有办法同时获取两台显示器的DPI?给出的示例在监视器之间移动WPF应用程序(笔记本电脑上为120,备用电脑上为96)时有效,但我需要获取第二个监视器的DPI,而无需将应用程序移动到那里。@Issac要获取每个监视器的DPI,您需要通过P/Invoke调用函数。要获得每监视器DPI的总体概述,请选中。@Isaclevin是否确实需要这样做?如果您确保您的应用程序支持监视器DPI,您将获得正确的屏幕边界。你只是想把分辨率乘以DPI还是别的什么?正如
Screen.Bounds
@Luaan所报告的那样,表单在另一个显示器上的空间实际上会更少,我正在尝试获取两个显示器的边界和DPI。目前,我的流程所做的是获取两个监视器(通过调用getting AllScreens member),然后检索每个监视器的边界并操作一个图像以适应这些边界。我遇到的问题是,笔记本电脑显示器的分辨率是错误的,而辅助显示器的分辨率是正确的。我已经设置了DPI aware,但两者的DPI都是96.0。我不确定我遗漏了什么,但我知道我还需要一个步骤。@Isaclevin听起来你似乎只知道系统DPI,而不知道监视器DPI。您是否在任务管理器(或资源管理器,忘记了哪个)中验证了这一点?它应该显示操作系统兼容性(Windows 8.1)和DPI意识(监控DPI意识),如果你深入挖掘的话。谢谢!这是唯一的解决方案,它帮助我在Windows 8.1中使用屏幕共享程序和缩放一件事,在Windows 7上,此代码不是缩放分辨率所必需的,但是如果此代码在Windows 7上运行,try catch将不会捕获抛出的错误,它将使程序崩溃。您需要更改它正在检查的错误,或者在我的情况下,我只是将其设置为捕获任何异常。这实际上不适用于wpf应用程序。请参见第二个答案: