简体   繁体   English

Windows 应用程序在调试时使用 Win32.MoveWindow 调整大小错误地缩放了 125%

[英]Windows apps resized with Win32.MoveWindow while debugging are scaled incorrectly by 125%

I use 2560x1440 monitors scaled on Windows 10 to 125%.我使用在 Windows 10 到 125% 上缩放的 2560x1440 显示器。 I wrote a C# unit test case in Visual Studio 2019 that calls a DLL to 1) find the window handles of various apps (notepad, wordpad, etc) and 2) resize them to just under 100% of the monitor size.我在 Visual Studio 2019 中编写了一个 C# 单元测试用例,该用例将 DLL 调用为 1)找到各种应用程序的 window 句柄(记事本、写字板等),并将它们调整为显示器大小的 2%。 I used Win32.MoveWindow to do the move, like so:我使用Win32.MoveWindow进行移动,如下所示:

//    MoveWindow(hWnd, left, top, width, height)
Win32.MoveWindow(hWnd, 0, 0, 2500, 1400, true);

The problem is that while debugging in the unit test, Windows10 scales up the 2500 and 1400 pixel numbers by 125% and moves the windows to that larger size.问题在于,在单元测试中进行调试时,Windows10 将 2500 和 1400 像素数放大了 125%,并将 windows 移动到更大的尺寸。 The windows then hang off the bottom and right edges of the screen. windows 然后挂在屏幕的底部和右侧边缘。

In contrast, when I run the same DLL code from a skeleton Windows Forms app (and while not debugging), the code works fine, and Windows resizes the Notepad and Wordpad app windows correctly. In contrast, when I run the same DLL code from a skeleton Windows Forms app (and while not debugging), the code works fine, and Windows resizes the Notepad and Wordpad app windows correctly.

I pass in the same numbers to Win32.MoveWindow in both cases.在这两种情况下,我都将相同的数字传递给Win32.MoveWindow

In case it matters, for the DLL code, I have tried endless combinations of the app.config and app.manifest settings for my DLL code that calls Win32.MoveWindow (and am targeting NET 4.7.2) but without success.万一这很重要,对于 DLL 代码,我已经尝试了 app.config 和 app.manifest 设置的无限组合,用于调用Win32.MoveWindow (并且我的目标是 NET 4.7.2)的 DLL 代码,但没有成功。

For the skeleton Forms app, I have tried 4.6.1 and 4.7.2 with no DPI settings in app.config and the "dpiAware=true" enabled in the app.manifest.对于骨架 Forms 应用程序,我尝试了 4.6.1 和 4.7.2,在 app.config 中没有 DPI 设置,并且在 app.manifest 中启用了“dpiAware=true”。 (Of course, neither the skeleton Forms app nor the DLL are DPI aware. I just tried the setting on and off.) (当然,骨架 Forms 应用程序和 DLL 都不是 DPI 感知的。我只是尝试打开和关闭设置。)

The only thing that seems to make a difference is whether I am debugging.唯一似乎有所作为的是我是否在调试。 I expected that I could use the normal screen pixels from the OS screen boundaries when I did MoveWindow operations, but that isn't working well when debugging.我希望在执行 MoveWindow 操作时可以使用来自操作系统屏幕边界的正常屏幕像素,但在调试时效果不佳。

What is the proper way to resize other apps with Win32.MoveWindow ?使用Win32.MoveWindow调整其他应用程序大小的正确方法是什么? Should my app determine the current scaling factor and then down-scale the numbers that I pass to Win32.MoveWindow ?我的应用程序是否应该确定当前的比例因子,然后缩小我传递给Win32.MoveWindow的数字? (I would pass 2500/1.25 = 2000 to Win32.MoveWindow , for example, for 125% scaling.) (例如,我会将 2500/1.25 = 2000 传递给Win32.MoveWindow以进行 125% 缩放。)

Is the debugger supposed to interfere with scaling and sizing like this?调试器是否应该像这样干扰缩放和调整大小? Is it a known problem?这是一个已知问题吗?

@selbie was totally correct and exactly on the target with his comment. @selbie 的评论完全正确,并且完全符合目标。 He was even kind enough to bold one of the key statement lines for me to draw my attention to it.他甚至好心地将其中一条关键语句加粗,以引起我的注意。 @selbie made it easy for me to solve the problem. @selbie 让我很容易解决问题。 I have included my test code fragments below.我在下面包含了我的测试代码片段。

Windows Behavior Windows 行为

As @selbie pointed out, if 125% scaling is enabled in the Accessibility Settings to make everything bigger, Windows reports different screen sizes to aware and unaware processes.正如@selbie 指出的那样,如果在“辅助功能设置”中启用了 125% 缩放以使一切都变大,Windows 会向有意识和无意识进程报告不同的屏幕尺寸。

For DPI-aware processes, Windows will report 2560x1440 because they are supposed to down-scale their thinking so that Windows can scale it back up 125% to produce sharp text, etc.对于 DPI 感知进程,Windows 将报告 2560x1440,因为他们应该缩小他们的思维,以便 Windows 可以将其放大 125% 以产生清晰的文本等。

For DPI-unaware processes, Windows will report 2048x1152 to the caller so the caller thinks the screen is smaller than it really is.对于不知道 DPI 的进程,Windows 将向调用者报告 2048x1152,因此调用者认为屏幕比实际小。 Windows scales up the caller's orders by 125% to make the caller's sizes fit the hardware screen size (2560x1440). Windows 将调用者的订单放大 125% 以使调用者的尺寸适合硬件屏幕尺寸 (2560x1440)。

The Problem问题

The problem I had was that my unit test code (DPI unaware) was using the hardware sizes in my DLL code (2560x1440), obtained from a database and not the OS, so when Windows scaled it up, my relocated windows were bigger than the hardware screen size. The problem I had was that my unit test code (DPI unaware) was using the hardware sizes in my DLL code (2560x1440), obtained from a database and not the OS, so when Windows scaled it up, my relocated windows were bigger than the硬件屏幕尺寸。

When the same DLL was used in a DPI-aware Forms app, Windows allowed for everything (produced no net scaling up) and the relocated windows fit the hardware screens. When the same DLL was used in a DPI-aware Forms app, Windows allowed for everything (produced no net scaling up) and the relocated windows fit the hardware screens.

The Solutions解决方案

The first solution is to make your calling process DPI-aware so that you can use the hardware screen sizes in your code.第一个解决方案是让您的调用进程能够识别 DPI,以便您可以在代码中使用硬件屏幕尺寸。 Do this by calling the Win32 API in NET 4.6 and above.通过在 NET 4.6 及更高版本中调用 Win32 API 来执行此操作。 This is what I used in my unit test to make it work properly.这是我在单元测试中使用的,以使其正常工作。

[STAThread]
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool SetProcessDPIAware();

static void Main() {
    if (Environment.OSVersion.Version.Major >= 6) SetProcessDPIAware();
    ... either ConsoleApp code or Windows.Forms code here
}

The second solution is to enable DPI-awareness in the EXE app.manifest file.第二种解决方案是在 EXE app.manifest文件中启用 DPI 感知。 Just uncomment the default XML code in the default app.manifest file produced by AddNew in Visual Studio.只需在 Visual Studio 中 AddNew 生成的默认app.manifest文件中取消注释默认 XML 代码即可。

APP.MANIFEST FILE
<application xmlns = "urn:schemas-microsoft-com:asm.v3" >
  <windowsSettings >
  <dpiAware xmlns = "http://schemas.microsoft.com/SMI/2005/WindowsSettings" >
      true </dpiAware >
  </windowsSettings >
</application >

In NET 4.7 and above, you can also use the new PerMonitorV2 DPI settings in the app.config file, not the `app.manifest' file.在 NET 4.7 及更高版本中,您还可以在app.config文件中使用新的PerMonitorV2 DPI 设置,而不是在“app.manifest”文件中。 This apparently lets you use different DPI-awareness for different monitors.这显然可以让您对不同的显示器使用不同的 DPI 感知。 (I have not tried this yet, but I mention it here for completeness.) (我还没有尝试过,但为了完整起见,我在这里提到它。)

<configuration>
    <!--requires NET 4.7, and the default is false />
    <System.Windows.Forms.ApplicationConfigurationSection>
        <add key="DpiAwareness" value="PerMonitorV2" />
        <add key="EnableWindowsFormsHighDpiAutoResizing" value="false" />
    </System.Windows.Forms.ApplicationConfigurationSection>
</configuration>

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

相关问题 Win7中的图标文件无效,字体缩放为125% - Icon file invalid in Win7 only with fonts scaled to 125% Microsoft.Win32.OpenFileDialog 在调试时不显示? - Microsoft.Win32.OpenFileDialog dosn't show while debugging? win 8应用程序中的Windows身份验证 - windows authentication in win 8 apps user32 MoveWindow在C#,Windows 7,控制台应用程序中不起作用 - user32 MoveWindow doesnt work in C#, windows 7, console application 调试单元测试时,“ System.ComponentModel.Win32Exception:操作成功完成” - 'System.ComponentModel.Win32Exception: The operation completed successfully' while debugging unit test 在Windows 8.1上调试可移植DLL时VS 2013未处理的Win32异常 - VS 2013 unhandled win32 exception when debugging portable dll on Windows 8.1 企业 Enterprise.windows.win32.win32 - Enterprise Enterprise.windows.win32.win32 Visual Studio 2008中的“源文件不同...”消息是在x64 Windows上调试x32应用程序的结果 - “The source file is different…” message in Visual Studio 2008 is result of debugging x32 apps on x64 Windows 如何在Windows 7中调用Win32 DLL - How to call win32 dll in windows 7 在Windows 7上查询win32_NetworkConnection速度很慢 - Querying win32_NetworkConnection is slow on Windows 7
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM