c# - 禁用高 DPI 缩放

标签 c# .net powershell winapi

我想在启用屏幕缩放时从我的代码中获取正确的数据。所以我正在使用 SetProcessDPIAware()功能:

using namespace System.Windows.Forms

Clear-Host
Add-Type -AssemblyName System.Windows.Forms
Add-Type -Name User32 -Namespace W32 '
[DllImport("user32.dll")]
public static extern bool SetProcessDPIAware();'


[Cursor]::Position | Write-Host
[Screen]::PrimaryScreen.Bounds.Size | Write-Host
[SystemInformation]::PrimaryMonitorSize | Write-Host

[W32.User32]::SetProcessDPIAware()

[Cursor]::Position | Write-Host
[Screen]::PrimaryScreen.Bounds.Size | Write-Host
[SystemInformation]::PrimaryMonitorSize | Write-Host

输出:

{X=630,Y=313}             # ❌ incorrect data
{Width=2048, Height=864}  # ❌ incorrect data
{Width=2048, Height=864}  # ❌ incorrect data
True
{X=788,Y=391}             # ✔️ data became correct
{Width=2048, Height=864}  # ❌ still incorrect data
{Width=2560, Height=1080} # ✔️ data became correct

与c#代码相同的情况:

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
 
public class Class1
{
    [DllImport("user32.dll")]
    static extern bool SetProcessDPIAware();

    public static void Main()
    {
        Console.WriteLine("\n");

        Console.WriteLine(Cursor.Position);
        Console.WriteLine(Screen.PrimaryScreen.Bounds.Size);
        Console.WriteLine(SystemInformation.PrimaryMonitorSize);

        Console.WriteLine(SetProcessDPIAware());

        Console.WriteLine(Cursor.Position);
        Console.WriteLine(Screen.PrimaryScreen.Bounds.Size);
        Console.WriteLine(SystemInformation.PrimaryMonitorSize);
    }
}

那么这是 Screen.PrimaryScreen.Bounds 的错误,还是我必须执行其他操作才能从此属性获取正确的数据?

如果唯一的方法是使用 SystemInformation 类,那么我如何获取有关第二个显示器的数据,而不仅仅是有关主要显示器的数据?

有没有办法设置this powershell.exe/powershell_ise.exe 的设置 ?

最佳答案

这是我使用并为我工作的:

Add-Type -TypeDefinition @'
using System; 
using System.Runtime.InteropServices;
using System.Drawing;

public class DPI
{  
    [DllImport("gdi32.dll")]
    static extern int GetDeviceCaps(IntPtr hdc, int nIndex);

    public enum DeviceCap
    {
        VERTRES = 10,
        DESKTOPVERTRES = 117
    } 

    public static float scaling()
    {
        Graphics g = Graphics.FromHwnd(IntPtr.Zero);
        IntPtr desktop = g.GetHdc();
        int LogicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.VERTRES);
        int PhysicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.DESKTOPVERTRES);

        return (float)PhysicalScreenHeight / (float)LogicalScreenHeight;
    }
}
'@ -ReferencedAssemblies System.Drawing -IgnoreWarnings -WarningAction Ignore

然后你可以像这样调用这个类并得到 DPI:

$DPI = [math]::round([dpi]::scaling(), 2) * 100
$bounds = [System.Windows.Forms.Screen]::PrimaryScreen.WorkingArea
$bounds.Width = ($bounds.Width / 100) * $DPI
$bounds.Height = ($bounds.Height / 100) * $DPI

最后,始终使用相对尺寸,例如:

$form.Size = [System.Drawing.Size]::new(($bounds.Width / X),($bounds.Height / X))
$form.Add_Resize({
    $txtBox.Size = [System.Drawing.Size]::new(($this.Width - X), XX)
})

依此类推,其中 X 可以是 intdouble


  • 左显示器:1920x1080 - 175% 缩放比例
  • 右监视器:1920x1080 - 100% 缩放

2mons

关于c# - 禁用高 DPI 缩放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69786234/

相关文章:

c# - 系统参数异常 : DataGridViewComboBoxCell value is not valid

powershell - 在文件名中查找替换文本-Powershell

powershell - 如何从 PowerShell 调用显式实现的接口(interface)方法?

c# - ExecuteScript 上的 Selenium 超时

.net - 调试器可视化工具不工作?我是否错误地注册了它?

c# - CLR 如何知道给定的程序集是正确的?

powershell - 计算Powershell中处理功能的时间

c# - 在 C# 中通过 XML 发送潜在敏感数据

c# - 为什么添加返回类型会阻止我使用方法组语法?

c# - 为什么文件 IFormFile = null?