简体   繁体   English

禁用高 DPI 缩放

[英]Disable high DPI scaling

I want to get correct data from my code when screen scaling is enabled.我想在启用屏幕缩放时从我的代码中获取正确的数据。 So i'm using SetProcessDPIAware() function:所以我使用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

Output:输出:

{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

The same situation with c# code:与 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);
    }
}

So is this a bug of Screen.PrimaryScreen.Bounds or i have to do something else to get correct data from this property?那么这是Screen.PrimaryScreen.Bounds的错误还是我必须做其他事情才能从此属性中获取正确的数据?

And if the only way is to use the SystemInformation class, then how do I get data about the second monitor, not only about the Primary one?如果唯一的方法是使用SystemInformation类,那么我如何获取有关第二台监视器的数据,而不仅仅是有关主要监视器的数据?

OR Is there a way to set this setting for powershell.exe / powershell_ise.exe ?或者有没有办法为 powershell.exe / powershell_ise.exe 设置设置?

This is what I use and works for me:这是我使用并为我工作的内容:

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

Then you can call this class and get the DPI like:然后你可以调用这个类并获得 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

And lastly, always use relative sizes like:最后,始终使用相对大小,例如:

$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)
})

And so on, where X can be an int or double .依此类推,其中X可以是intdouble


  • Left Monitor: 1920x1080 - 175% Scaling左监视器:1920x1080 - 175% 缩放
  • Right Monitor: 1920x1080 - 100% Scaling右监视器:1920x1080 - 100% 缩放

2mons

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 WinForm 的 Windows 高 DPI 缩放 - Windows High DPI Scaling for WinForm 在 WPF 中禁用上下文菜单/弹出窗口的 DPI 缩放 - Disable DPI scaling of ContextMenus/Popups in WPF C# WinForms 禁用 DPI 缩放 - C# WinForms disable DPI scaling Winforms应用程序在绘制图表时更改高dpi监视器上的缩放比例 - Winforms application changes scaling on high dpi monitor when drawing a chart 更改c#中的“覆盖高DPI缩放行为” - Change “Override high DPI scaling behavior” in c# 如何通过代码以编程方式将“覆盖高 DPI 缩放”设置为“应用程序” - How to set “Override high DPI scaling” to “Application” programmatically through code 无法让NotifyIcon加载高DPI资源以进行DPI缩放> = 150% - Can't get NotifyIcon to load high DPI resource for DPI scaling >= 150% Windows 8中的字体缩放与Windows 7中的字体缩放(在高DPI下-144) - Font Scaling in Windows 8 vs Font Scaling in Windows 7 (under high DPI - 144) .NET WinForms 高 DPI 缩放 - 如何在显示设置更改后强制 forms 正确显示? - .NET WinForms high DPI Scaling - how to force forms to display correctly after display settings change? WinForms:如何修复 Forms 在具有不同分辨率/缩放的高 DPI、多监视器环境 (PerMonitorV2) 中的不正确缩放 - WinForms: How to fix incorrect scaling of Forms in high-DPI, multi-monitor environments (PerMonitorV2) with different resolution/scaling
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM