-2

我的应用是用VC++(win32)开发的插件。我能找到的解决方案对我不起作用。

我有两个选择:

  1. 禁用我的 DLL 插件的 DPI 更改。这意味着我的插件不会受到 DPI 更改的影响。
  2. 根据 DPI 更改缩放所有控件。

请帮忙。

谢谢。

4

1 回答 1

1

1. 当有人重新配置 DPI 时,禁用 DPI 对我的应用程序 UI 的影响。需要帮助:如果可能,如何以编程方式进行。

这是不可能的。阿德里安已经告诉过你了。DPI 是用户设置,而不是应用程序设置。如果用户想要更改他们的 DPI,他们可以这样做。他们还可以应用向后兼容的技巧来关闭特定应用程序的高 DPI,但该功能对应用程序不可用。作为开发人员,您应该确保支持高 DPI 环境,而不是禁用它。

作为应用程序开发人员,您唯一能做的就是不能表明您的应用程序是 DPI 感知的。这大致相当于在额头上贴着“白痴”标志四处走动。你可能会发现人们对你的缺点稍微宽容一些,但他们不会太尊重你,也可能不会经常和你一起出去玩。Windows 也会做同样的事情:它会向你隐藏关于用户实际 DPI 设置的真相(你无法处理真相),而是会自动扩展你的界面以匹配。效果是丑陋的。

当然,您还说您正在创建一个插件 DLL,它会改变一些事情。DLL 不能改变整个进程的 DPI 感知,因为这是由主机应用程序决定的。如果宿主应用程序表明它支持高 DPI,那么您的 DLL 也必须支持高 DPI。这是一个全有或全无的设置,就像“白痴”标志一样。

2. 根据 DPI 变化缩放我的应用程序的 UI。需要帮助:如何确定当前的 DPI 以及如何相应地缩放 UI?是否有必要缩放每个组件或任何其他方式来自动缩放它们。

为了正确确定当前的 DPI 设置,您需要向 Windows 表明您不是白痴,您的应用程序支持高 DPI。如上所述,如果您不这样做,Windows 将假定您无法处理真相并欺骗您。但是正如我们在上面建立的,这可能不适用于您,因为您正在创建一个在另一个进程的上下文中运行的 DLL,该进程已经将自己建立为高 DPI 感知。

因此,您需要做的是确定 DPI 比例因子。在高 DPI 环境中运行时,您需要相应地缩放用户界面元素。基线 DPI 设置为 96。以下代码SIZE相对于该基线缩放结构(定义宽度和高度):

void ScaleDpi(SIZE& size)
{
    // Determine the current screen DPI.
    const HDC hDC = GetDC(NULL);
    const int dpiX = GetDeviceCaps(hDC, LOGPIXELSX);
    const int dpiY = GetDeviceCaps(hDC, LOGPIXELSY);
    ReleaseDC(NULL, hDC);

    // Perform the scaling.
    size.cx = MulDiv(size.cx, dpiX, 96);
    size.cy = MulDiv(size.cy, dpiY, 96);
}

但是,如果您遵循良好的设计实践,您可能不需要手动缩放每个控件。在资源文件中定义窗口和对话框时(例如,使用 Visual Studio 对话框编辑器),您以逻辑单元(称为 DLU 或对话框单元)指定布局。这些单位独立于任何特定的 DPI 设置,因此比使用像素之类的东西更可取。因此,带有几个控件的简单对话框不需要特殊的缩放工作。如果您在运行时创建和/或布局控件,则只需要执行手动缩放。

您将在 MSDN 上的编写高 DPI Win32 应用程序文章中找到有关如何编写高 DPI 感知应用程序的更多提示和技术。而且我不只是为了说 RTFM 而链接它——它实际上非常有帮助,我强烈建议阅读它。

制作 RealWorld Icon 和 Cursor 编辑器的人还在他们的网站上维护了一篇有用的文章:Windows Vista 和 Windows 7 中的 DPI 感知应用程序

于 2013-05-27T10:20:41.700 回答