2

Let's suppose that I have two screens, side by side:

  1. 1920x1080 100% DPI

  2. 1360x768 125% DPI

Screens

For my Window, this means:

  1. 1920x1080: Ok

  2. 1088x614: Not ok, it's divided by 1,25 because of the scaling factor.

Turning into this:

  1. 1920x1080 + 1088x614: 3008x1080

I want to use the CopyFromScreen/BitBlt methods. These methods ignore all DPI info, making the Left and Top properties (of a window, for example) useless if inside a high dpi screen. Or left to a high dpi screen, since it behaves like 1 screen, example:

Screens inverted

So whenever I need to get a screen point from within a set of screens with at least one having a high DPI, it will return a smaller point.

Is there any way to get the true (by true, ignoring the scaling factor) XY info from a set of screens with (at least one) high DPI?

I already tried the managed PointToScreen and the unmanaged ClientToScreen methods, both resulting the same "right" point.

Please, read

I want to take screenshots of the screen based of the position of my Window.

I have two monitors, one with 100% DPI, other with 125% DPI.

If my Window is inside the 1st monitor, the screenshot based on the Left/Top properties of my Window works.

If my Window is inside the second monitor, the screenshot won't take the right spot!

Because

The BitBlt API method ignores the scaling of the screens. Example:

Screenshot of the point 100;100 will be right, because it's inside the 1st screen.

Screenshot of the point 1950;100 won't be right, because it's inside the 2nd screen. Notice that it's 30 pixels to the right.

Why?

As said earlier, for my app, the 125% DPI reduces the screen resolution to 1088x614, but for the BitBlt method, it is still 1360x768.

So I can't convert the Left/Top properties, because it will be wrong, since there is a 100% DPI screen to the left.

Example of the Left property:

I believe this is the right way to convert:

1920px + 50px: 100% + 125%: 1920 + 62: 1982px

And this is the proposed version:

1920px + 50px: 100% + 125%: 2400 + 62: 2462px

See, if I simple convert the current Left property based on the DPI of the current Window, on this case my second screen, I'll also be converting the values of my first screen. This should not happen.

Nicke Manarin
  • 3,026
  • 4
  • 37
  • 79
  • Your question is tagged with WPF if your copy operations are due to different control sizes You might look at https://blogs.msdn.microsoft.com/dotnet/2016/03/30/announcing-the-net-framework-4-6-2-preview/ where WPF gets multi DPI per monitor support. – Alois Kraus Apr 24 '16 at 07:08
  • This is not WPF specific, it happens with Winforms too. I already tried to disable DPI awareness by changing the assembly.cs file. With no success. – Nicke Manarin Apr 24 '16 at 15:02
  • Your question appears to be specifically about conversion between WPF's 96dpi coordinate system to device coordinates, hence the marked duplciate. If you believe the marked duplicate doesn't address your needs, please provide a good [mcve] that reliably reproduces your problem (on appropriately configured hardware, of course), with a precise explanation of what you've tried to solve it and why converting from WPF coordinates to device coordinates doesn't work for you. – Peter Duniho Apr 24 '16 at 20:57
  • Frankly, IMHO the best answer here is "don't do that". Explicitly scaling each screen differently is basically _asking_ for different results on each screen and for images on one screen to not match dimensionally those on the other. – Peter Duniho Apr 24 '16 at 20:57
  • See also http://stackoverflow.com/q/5066958, http://stackoverflow.com/q/22668051, and http://stackoverflow.com/q/24640981 – Peter Duniho Apr 24 '16 at 20:59
  • I need to scale each screen differently, because of the `PerMonitorDPI` available with W8.1+. – Nicke Manarin Apr 25 '16 at 11:42
  • If I have just `one` screen, the DPI does not matter, since I already use that method to multiply the values to match the current scale of the screen. **This is not the case of this problem.** – Nicke Manarin Apr 25 '16 at 11:44

0 Answers0