Quiero obtener los datos correctos de mi código cuando la escala de pantalla está habilitada. Así que estoy usando la función 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-HostProducción:
{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 correctLa misma situación con el código 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); } } Entonces, ¿es esto un error de Screen.PrimaryScreen.Bounds o tengo que hacer algo más para obtener los datos correctos de esta propiedad?
Y si la única forma es usar la clase SystemInformation , entonces, ¿cómo obtengo datos sobre el segundo monitor, no solo sobre el principal?
O ¿Hay alguna forma de establecer esta configuración para powershell.exe/powershell_ise.exe?
Esto es lo que uso y funciona para mí:
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 IgnoreLuego puede llamar a esta clase y obtener el DPI como:
$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) * $DPIY, por último, siempre use tamaños relativos como:
$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) }) Y así sucesivamente, donde X puede ser un int o double .