GetClientRect 返回缩放尺寸?

Zac*_*Saw 5 c# pinvoke winapi winforms autoscalemode

我打电话 GetClientRect在 C# 中通过 pinvoke以获取我用作 DirectX 渲染目标区域的面板的尺寸(在 WindowsForm 上)。我本以为 WinAPI 给了我未缩放的(即,无论 Windows 显示 DPI 设置如何,返回的值都应该相同)尺寸,但它似乎给了我缩放的尺寸(至少在 Windows 8.1 上,因为我还没有测试过)在其他操作系统上)。

ClientRectangle属性还返回与 相同的缩放尺寸GetClientRect。当我将表单更改AutoScaleModenone.

这是预期的行为GetClientRect吗?如果是这样,我如何获得未缩放的尺寸?

编辑:这仅影响 Windows 8.1。在 Windows 7 上对其进行了测试,GetClientRect 返回未缩放的尺寸!

Cod*_*ray 3

P/Invoking 没有任何优势GetClientRect。通过查询该属性,您会得到完全相同的结果ClientRectangle

是的,其中任何一个都会返回以物理像素为单位的客户区域的大小,这显然不是您想要的。

您可能正在寻找 方法ID2D1RenderTarget::GetSize该方法返回渲染目标的大小(以设备无关像素 (DIP) 为单位)。

如果您必须转换物理像素(例如,来自鼠标事件),那么您可以使用类似的方法ID2D1Factory::GetDesktopDpi来获取当前缩放因子,您可以使用该因子将物理像素转换为 DIP。

您在 Windows 8.1 中看到不同行为的原因可能是它处理 DPI 缩放的方式发生了变化。您可能会发现,指示您的应用程序支持 DPI 是比处理上述内容更简单的解决方案。这将阻止 UI 自动缩放以匹配当前的 DPI 设置。您可以通过将以下内容添加到应用程序的清单中来完成此操作:

<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>
Run Code Online (Sandbox Code Playgroud)

在 Visual Studio 中,右键单击该项目,然后单击“添加”->“新项目”。选择“应用程序清单文件”并添加上述代码。

相关阅读:编写支持 DPI 的桌面和 Win32 应用程序