winapihighdpi

How to know current bitmap-scaling factor for a Windows HWND?


I have a small C# program, HelloCs.cs, like this:

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);
     }    
}

== CASE 1.0 ==

When run on a default Windows 7 system. It shows like this, nothing special:

enter image description here

The window width & height is 200 & 100 respectively.

== CASE 1.5 ==

When I set system DPI scaling to 150% (and restart OS), C# program still reports window width & height as before, BUT, the window's actual on-screen size(pixel count) becomes 300 and 150. That means, Windows system has apply so-called bitmap-scaling on my window.

enter image description here

Then my question is: How do I know(in my own program, or with an HWND handle), whether the system has applied bitmap-scaling to the window, and what is the scaling factor.

On Window 10, things becomes more complicated, because Windows 10 may apply different scaling factor to different HWND, according to the HWND's current residing monitor.

I hope to get an answer applicable to Both Windows 7 and 10.


Solution

  • After one month's investigation, I find it a VERY complicated problem. The situation on Windows 7, Windows 8.1 and Win10.1607+ are all different.

    Finally, I managed to composed a demo program(based on an open source project) that can determine the bitmap-stretching factor by the system.

    Talking is cheap, so here is my working code: https://github.com/chjfth/window-finder-control

    Feature:

    See my demo UI below

    Figure 1:

    enter image description here

    Explanation:

    They are both 400x241, so the target-window is not-bitmap stretched.

    Figure 2: On Windows 7 with global DPI-scaling set to 150%, physical RECT is 150% larger than the virtual RECT(compared by width or height, width 600 vs 400). So, the target windows is 150% stretched.

    enter image description here

    Figure 3: On Win10.1909, we can also see 150% bitmap-stretched window.

    enter image description here

    Figure 4: On Win10.1909, we can even see bitmap-shrunk HWND. It happens when the caller is SysDpi-aware(150%), and, the target-windows is also SysDpi-aware but resides on a 100%-scaling monitor.

    enter image description here