0

By using Screen (Screen.AllScreens for multiscreens) class, the basic information of screens can be derived easily. However, it seems hard to get DPI or monitor scale information for each screen in multi-monitor setting.

I've found some solutions for apps with 'DPI aware' in How to get Windows Display settings?

However, as written above, they mostly require either the running app as 'DPI aware' or a single screen environment (that any Form or Control must be located in the desired screen to calculate DPI value).

I just want to get the 'scale value (100%, 125%.. in Display Setting > Scale and Layout)' (it is okay not to be DPI) for each monitor. The important thing is that the app is not declared as 'DPI aware' and it won't be. It's a WinForm legacy program.

Is it possible to do it in that setting?

Thank you in advance.

klados
  • 644
  • 10
  • 29
  • 2
    You're literally describing wanting your application to be aware of DPI, but you don't want to declare it DPI Aware. Is there a *solid technical reason* for not making the obvious change? – Damien_The_Unbeliever Mar 08 '21 at 10:03
  • [Enumeration and Display Control](https://docs.microsoft.com/en-us/windows/win32/gdi/enumeration-and-display-control) -- [Multiple Monitor System Metrics](https://docs.microsoft.com/en-us/windows/win32/gdi/multiple-monitor-system-metrics) -- [Using SetWindowPos with multiple monitors](https://stackoverflow.com/a/53026765/7444103) – Jimi Mar 08 '21 at 10:09
  • @Damien_The_Unbeliever My application needs to calculate a `Form` location according to DPI(or Scale) for arranging through multi-screens. However, declaring it as DPI-aware makes both `WinForm Controls` and other 3rd-party ones in the app quite messy, so that I don't plan to modify the bunch of whole codes and UIs. Just want to know the raw value of DPI or Scale setting of screens. The codes are already written, only the scale number is needed parameter. – klados Mar 08 '21 at 10:12
  • 1
    If you want to keep your app Dpi-UnAware, use the virtualized measures you get from those methods. The System scales your Forms for you. You don't really need to know the scale factor of a Monitor to move your Forms to a different Screen. Different story if you have a DpiAware app and you want to scale it to adapt its layout to different Screen sizes and Font scaling (which is the harder and messier part in WinForms, IMO, since there's still lack of support for this). – Jimi Mar 08 '21 at 10:21
  • @Jimi Thanks. I've just tried `EnumDisplayMonitors` user32.dll API and it appears to show the same result as just using `Screen.AllScreens(0).Bounds`, which is not desired. I understand worth making DPI-aware, and I know that 'System will do it for you'. I've tried once and turned out that definitely, the System does not do *all* of them for me. (Mixed with native WinForm controls and 3rd-party ones mingled together to make the worst layout, plus locating a `Form` does not work as intended). – klados Mar 08 '21 at 10:53
  • The application has to calculate with the scale number (not the Windows automatically adjusted for me) to locate a certain `Form` precisely. The scale number (1.25, 125%, 1280/1024 or 120/96) is the only parameter missing, the rest of the part is already coded. – klados Mar 08 '21 at 10:53
  • You should probably use UI Automation for this. Anyway, see [GetDeviceCaps](https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-getdevicecaps). To understand better what the notes there are telling you, read also the notes I posted [here](https://stackoverflow.com/a/53026765/7444103), about the VirtualScreen layout and Monitor identifiers. – Jimi Mar 08 '21 at 11:03
  • @Jimi Thanks. Your note is a really comprehensive and nice one, but it says "If the application is not DPIAware ...All measures will be uniformed to a default 96 Dpi". Anyway, the API that I have to use with a scale factor is `SHAppBarMessage`. It requires non-adjusted Top and Left in pixel. For example, if just putting Screen.AllScreens(1).Bounds values to `SHAppBarMessage` in 125% scaled monitor, the AppBar fail to be located properly. I will read GetDeviceCaps. – klados Mar 08 '21 at 11:13

0 Answers0