I'm calling GetClientRect
via pinvoke in C# to get dimensions of a panel (on WindowsForm) I'm using as DirectX render target area. I would've thought that WinAPI gives me the unscaled (i.e. returned values should be the same regardless of Windows display DPI settings) dimensions, but it appears to give me the scaled one instead (at least on Windows 8.1 as I have not tested it on other OSes).
The ClientRectangle
property also returns the same scaled dimensions as GetClientRect
. This remains the same when I've changed the form AutoScaleMode
to none
.
Is that the expected behavior with GetClientRect
? If so, how do I get the unscaled dimensions?
EDIT: This only affects Windows 8.1. Tested it on Windows 7 and GetClientRect returns the unscaled dimensions!
There's no advantage to P/Invoking GetClientRect
. You get exactly the same thing by querying the ClientRectangle
property.
And yes, either one of those is going to return the size of the client area in physical pixels, which is apparently not what you want.
You are probably looking for the ID2D1RenderTarget::GetSize
method, which returns the size of the render target in device-independent pixels (DIPs).
If you must convert physical pixels (e.g., from mouse events) then you can use something like ID2D1Factory::GetDesktopDpi
to get the current scaling factors, which you can use to convert physical pixels into DIPs.
The reason you're seeing different behavior in Windows 8.1 is probably the result of changes to the way it handles DPI scaling. You may find that indicating your application is DPI-aware is an easier solution than futzing with the above. That will stop the UI from being automatically scaled to match the current DPI settings. You do this by adding the following to the application's manifest:
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>True/PM</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
</assembly>
From Visual Studio, right-click on the project and click "Add" -> "New Item". Choose the "Application Manifest File" and add the above code.
Related reading: Writing DPI-Aware Desktop and Win32 Applications
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With