5

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

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

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

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

4

1 回答 1

3

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

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

您可能正在寻找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>

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

相关阅读:编写 DPI 感知桌面和 Win32 应用程序

于 2014-08-15T16:15:12.797 回答