c# - GetClientRect 返回缩放尺寸?

标签 c# winforms winapi pinvoke autoscalemode

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

ClientRectangle 属性也返回与 GetClientRect 相同的缩放尺寸。当我将 AutoScaleMode 的形式更改为 none 时,情况保持不变。

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

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

最佳答案

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

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

您可能正在寻找 ID2D1RenderTarget::GetSize method ,它以设备无关像素 (DIP) 返回渲染目标的大小。

如果您必须转换物理像素(例如,从鼠标事件),那么您可以使用类似 ID2D1Factory::GetDesktopDpi 的东西获取当前比例因子,您可以使用它来将物理像素转换为 DIP。

您在 Windows 8.1 中看到不同行为的原因可能是 changes to the way it handles DPI scaling 的结果.您可能会发现,指示您的应用程序是 DPI 感知的是一种比使用上述方法更简单的解决方案。这将阻止 UI 自动缩放以匹配当前的 DPI 设置。您可以通过将以下内容添加到应用程序的 list 中来执行此操作:

<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 中,右键单击项目并单击“添加”->“新建项”。选择“应用程序 list 文件”并添加以上代码。

相关阅读:Writing DPI-Aware Desktop and Win32 Applications

关于c# - GetClientRect 返回缩放尺寸?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25328065/

相关文章:

c# - 关闭对话框窗体关闭父窗体

c# - app.config 属于哪里?

C++ 从另一个 Win32 应用程序获取 GDI 原始文本

c++ - 是否可以将来自 Win32 EDIT 控件的文本输入存储在 C++ std::string 中?

c# - Datagridview 添加工具提示

c# - 接口(interface)、泛型和隐式操作

c# - 是否有 C# 格式说明符会省略前导零,除非值为零?

c# - 如何构建 C# WinForms Model-View-Presenter(被动 View )程序?

vb.net - 帮助以窗口形式将复选框列添加到 DataGridView

c++ - 设置/删除窗口子类时正确传递/删除数据