簡體   English   中英

禁用高 DPI 縮放

[英]Disable high DPI scaling

我想在啟用屏幕縮放時從我的代碼中獲取正確的數據。 所以我使用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類,那么我如何獲取有關第二台監視器的數據,而不僅僅是有關主要監視器的數據?

或者有沒有辦法為 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM