为什么powershell控制台错误地调整了我的GUI窗体的大小?

wbrvyc0a  于 2023-01-17  发布在  Shell
关注(0)|答案(1)|浏览(137)

我想在1920 x 1080像素的Windows 11屏幕上打开一个特定大小的powershell GUI窗体。设置中的系统缩放比例设置为125%。这不可能是一个异常配置。
作为测试,我尝试打开一个大小为屏幕四分之一的窗体,如下所示:

Add-Type -AssemblyName System.Windows.Forms

$form = New-Object System.Windows.Forms.Form
$form.width = 960
$form.height = 540
$GuiResponse = $Form.ShowDialog()

问题很简单-这在Powershell伊势中工作得很完美,但我无法让它在Powershell控制台中工作,因为窗口总是明显大于它应该的大小-我想是因为控制台正在执行某种反向缩放。
我当然可以自己缩放窗口,使窗口按比例缩小,以便在从控制台运行时保持正确的大小-但还有一个额外的相关问题,即写入窗口的任何文本都是模糊的,因为它被不适当地缩放(猜测)。
在堆栈溢出和其他地方已经有一些关于这类问题的讨论,但是我没有尝试解决这个问题。然而,它似乎是这样一个基本的问题,它肯定有一个简单的解决方案?

js81xvg6

js81xvg61#

您可以通过P/Invoke使Windows窗体DPI感知,方法是调用SetProcessDPIAware function

Add-Type -AssemblyName System.Windows.Forms
Add-Type -TypeDefinition '
public class DPIAware {
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern bool SetProcessDPIAware();
}
'

[System.Windows.Forms.Application]::EnableVisualStyles()
[void] [DPIAware]::SetProcessDPIAware()

$form = [System.Windows.Forms.Form]@{
    Width  = 960
    Height = 540
}
$form.ShowDialog()

有关更多相关信息,请参见Setting the default DPI awareness for a process
如果您想要调用MS文档中推荐的 * 较新 * 函数SetProcessDpiAwarenessContext,但请注意,此函数从Windows 10版本1607开始兼容,以下是实现的外观:

Add-Type -TypeDefinition '
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;

public class DPIAware {
    public static readonly IntPtr UNAWARE              = (IntPtr) (-1);
    public static readonly IntPtr SYSTEM_AWARE         = (IntPtr) (-2);
    public static readonly IntPtr PER_MONITOR_AWARE    = (IntPtr) (-3);
    public static readonly IntPtr PER_MONITOR_AWARE_V2 = (IntPtr) (-4);
    public static readonly IntPtr UNAWARE_GDISCALED    = (IntPtr) (-5);

    [DllImport("user32.dll", EntryPoint = "SetProcessDpiAwarenessContext", SetLastError = true)]
    private static extern bool NativeSetProcessDpiAwarenessContext(IntPtr Value);

    public static void SetProcessDpiAwarenessContext(IntPtr Value) {
        if (!NativeSetProcessDpiAwarenessContext(Value)) {
            throw new Win32Exception();
        }
    }
}
'

[DPIAware]::SetProcessDpiAwarenessContext([DPIAware]::PER_MONITOR_AWARE_V2)

相关问题