flutter在windows平台如何自定义dpi设置

flutter在windows平台如何自定义dpi设置

系统层级的支持(windows平台对高dpi的支持)

主要有两点:

  1. 设置系统的缩放比例 (系统及系统自带的app会根据这个设置来进行缩放;自己的app需要结合自己设置的dpi awareness来实现对应的dpi支持)
  2. 设置进程的dpi awareness(这个会影响某些系统api的返回值)

以DPI_AWARENESS_CONTEXT_UNAWARE举个例子,如果设置了这个值,会有一下几个影响:

  • 系统api,GetDpiForWindow的返回值是96,也就是1:1缩放时的值
  • 系统会根据用户设置的缩放比例,等比例的对程序界面进行缩放,这样会造成模糊。

这个也就是说,在程序不支持高dpi,没有2x,3x等对应缩放的切图时,可以设置这个。
如果有对应的高dpi的切图,却设置了这个,会造成程序拿不到系统的真实的dpi(只能拿到96这个dpi值),无法准确的使用对应的高倍图片。

一、设置缩放比例

在这里插入图片描述

二、设置进程的 DPI Awareness

相关链接
https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setprocessdpiawarenesscontext
https://learn.microsoft.com/en-us/windows/win32/hidpi/dpi-awareness-context?redirectedfrom=MSDN

框架层级的支持

QT

https://doc.qt.io/qt-5/highdpi.html

By default, Qt applications are set to Per-Monitor DPI Aware on Windows 8.1 or System-DPI Aware on older Windows versions. As of Qt 5.4, this level can be specified via a parameter to the platform plugin:

当然,可以通过系统api修改这个设置。系统api只能调一次,谁先调用谁生效。

QT还可以设置

QT_SCALE_FACTOR [numeric] defines a global scale factor for the whole application, including point-sized fonts.
来覆盖系统级别设置的缩放值,从而做到dpi的自定义设置。设置方式为:

qputenv("QT_SCALE_FACTOR", "3.0");

Flutter

不像QT,flutter没有可以覆盖系统定义的缩放值的方法。

修改flutter引擎源码,让flutter支持自定义设置dpi的缩放比例

看flutter的导出接口头文件flutter_windows.h可以发现两个api跟dpi相关,只能获取,无法设置。

// Gets the DPI for a given |hwnd|, depending on the supported APIs per
// windows version and DPI awareness mode. If nullptr is passed, returns the DPI
// of the primary monitor.
//
// This uses the same logic and fallback for older Windows versions that is used
// internally by Flutter to determine the DPI to use for displaying Flutter
// content, so should be used by any code (e.g., in plugins) that translates
// between Windows and Dart sizes/offsets.
FLUTTER_EXPORT UINT FlutterDesktopGetDpiForHWND(HWND hwnd);

// Gets the DPI for a given |monitor|. If the API is not available, a default
// DPI of 96 is returned.
//
// See FlutterDesktopGetDpiForHWND for more information.
FLUTTER_EXPORT UINT FlutterDesktopGetDpiForMonitor(HMONITOR monitor);

代码中的使用

bool Win32Window::Create(const std::wstring& title,
                         const Point& origin,
                         const Size& size) {
  Destroy();

  const wchar_t* window_class =
      WindowClassRegistrar::GetInstance()->GetWindowClass();

  const POINT target_point = {static_cast<LONG>(origin.x),
                              static_cast<LONG>(origin.y)};
  HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST);
  UINT dpi = FlutterDesktopGetDpiForMonitor(monitor);
  double scale_factor = dpi / 96.0;

通过查看上面接口的源码,可以发现,flutter的所有dpi相关的代码,可以归结到源文件:

// engine/shell/platform/windows/dpi_utils.cc

UINT GetDpiForHWND(HWND hwnd) {
  return GetHelper()->GetDpiForWindow(hwnd);
}

UINT GetDpiForMonitor(HMONITOR monitor) {
  return GetHelper()->GetDpiForMonitor(monitor);
}

因为这两个值都是从系统拿到的缩放值,可以修改这两个接口,来覆盖系统的缩放值。
有了这个,就可以给flutter加个导出设置缩放值的接口,来达到QT下QT_SCALE_FACTOR的类似效果。

  • 19
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值