I need to have WPF windows that is always 1:1 with physical pixels (DPI is always 96), and by this time I found no way to do this: application manifest or API methods for the awareness are useless, they just changing ways how the content is being scaled: as a bitmap or by the application. I need application always has the fixed, 100% scale, even if system settings are 200% per monitor or per whole system. Do you guys know some ways that could help?
For those who will be looking for the similar solution:
I found no way to force application do not scale together with the operating system, but found how to keep 1:1 scale.
First thing you need to do is to define that the application is dpi-aware, so it will not be scaled by the system but by application itself. Here is app.manifest code:
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/PM</dpiAware>
</windowsSettings>
</application>
</assembly>
Then you'll be able to get current scale for the visual:
double xScale = PresentationSource.FromVisual(someVisual).CompositionTarget.TransformToDevice.M11;
double yScale = PresentationSource.FromVisual(someVisual).CompositionTarget.TransformToDevice.M22;
And then you could bind layout transform to control (image in my case) to cancel scaling effect:
<Image.LayoutTransform>
<ScaleTransform ScaleX="{Binding ElementName=_this, Path=ScaleX}"
ScaleY="{Binding ElementName=_this, Path=ScaleY}" />
</Image.LayoutTransform>
Please note that proportions should be inverted, so ScaleX and ScaleY will have these values:
ScaleX = 1 / scaleX;
ScaleY = 1 / scaleY;