【问题标题】:How to know current bitmap-scaling factor for a Windows HWND?如何知道 Windows HWND 的当前位图缩放因子?
【发布时间】:2021-06-01 04:36:58
【问题描述】:

我有一个小的 C# 程序,HelloCs.cs,如下所示:

using System;
using System.Drawing;
using System.Windows.Forms;

class HelloWorld: Form
{
     public static void Main()
     {
          Application.Run(new HelloWorld());
     }
     public HelloWorld()
     {
          Text = "Hello World";
          BackColor = Color.White;

     }
     protected override void OnPaint(PaintEventArgs pea)
     {
          Graphics grfx = pea.Graphics;

          this.Width = 200;
          this.Height = 100;

          grfx.DrawString(
              $"({this.Width} , {this.Height}) Hello, Windows Forms!", 
              Font, Brushes.Black, 0, 0);

          base.OnPaint(pea);
     }    
}

== 案例 1.0 ==

在默认的 Windows 7 系统上运行时。它是这样显示的,没什么特别的:

窗口的宽度和高度分别为 200 和 100。

== 案例 1.5 ==

当我将系统 DPI 缩放设置为 150%(并重新启动操作系统)时,C# 程序仍然像以前一样报告窗口宽度和高度,但是,窗口的实际屏幕尺寸(像素数)变为 300 和 150。这意味着, Windows 系统在我的窗口上应用了所谓的bitmap-scaling

那么我的问题是:我怎么知道(在我自己的程序中,或者使用 HWND 句柄),系统是否对窗口应用了位图缩放,以及缩放因子是什么。

在 Window 10 上,事情变得更加复杂,因为 Windows 10 可能会根据 HWND 的当前驻留监视器对不同的 HWND 应用不同的缩放因子。

我希望得到一个适用于 Windows 7 和 10 的答案。

【问题讨论】:

  • GetWindowDpiAwarenessContext 似乎是您正在寻找的。不过,这只是 Windows 10。
  • 在这里试试我的答案:stackoverflow.com/a/32888078/403671
  • @SimonMourier 看起来你的答案不起作用。在 Win10.1909 上,当 DPI 缩放设置为 150% 时,调用 WinAPI GetDpiForWindow(this.Handle); 返回 96。我希望获得 144 的 DPI 值。
  • 我认为我的代码工作正常,我刚刚再次测试了它,但你可能会被清单的存在/不存在和内容所愚弄。挺复杂的事情...仔细阅读本文docs.microsoft.com/en-us/windows/win32/hidpi/… 或者提供一个复现项目,不仅仅是代码
  • @SimonMourier 谢谢。我正在寻找它。使用引用 和/或 的清单,GetDpiForWindow() 现在返回 144。因此,希望您的解决方案是正确的。我还在努力。

标签: winapi highdpi


【解决方案1】:

经过一个月的调查,我发现这是一个非常复杂的问题。 Windows 7、Windows 8.1、Win10.1607+的情况都不同。

最后,我编写了一个演示程序(基于一个开源项目),可以通过系统确定位图拉伸因子。

说话很便宜,所以这是我的工作代码: https://github.com/chjfth/window-finder-control

特点:

  • 在 Windows 7 和 Win10.1607+ 上,无论调用程序本身是 DPI 不感知、SysDpi 感知还是 Per-monitor 感知,我都可以准确判断。
  • 在 Windows 8.1 ~ Win10.1511 上,调用程序 必须 识别每个监视器才能准确地告诉它。这是由于缺乏对 Win81 基本混合模式 DPI 缩放的 API 支持。

在下面查看我的演示用户界面

图一:

解释:

  • WinRect通过调用GetWindowRect显示RECT值,即所谓的虚拟RECT大小。
  • 左上角的红色数字显示由调用程序“计算或推断”的目标窗口的物理尺寸。

它们都是 400x241,所以目标窗口不是位图拉伸的。

图 2:在全局 DPI 缩放设置为 150% 的 Windows 7 上,物理 RECT 比虚拟 RECT 大 150%(与宽度或高度相比,宽度 600 与 400)。因此,目标窗口被拉伸了 150%。

图 3:在 Win10.1909 上,我们也可以看到 150% 位图拉伸的窗口。

图 4:在 Win10.1909 上,我们甚至可以看到位图缩小的 HWND。当调用者支持 SysDpi(150%) 并且目标窗口也支持 SysDpi 但驻留在 100% 缩放监视器上时,就会发生这种情况。

【讨论】:

    猜你喜欢
    • 2013-02-15
    • 1970-01-01
    • 1970-01-01
    • 2014-04-03
    • 1970-01-01
    • 1970-01-01
    • 2022-07-01
    • 2016-01-06
    • 2016-09-12
    相关资源
    最近更新 更多