上官方的实现源码:
function TPlatformWin.GetDisplayMetrics: TDeviceDisplayMetrics; var R: TRect; begin Winapi.Windows.GetWindowRect(GetDesktopWindow, R); Result.PhysicalScreenSize := TSize.Create(R.Width, R.Height); Result.RawScreenSize := Result.PhysicalScreenSize; Result.LogicalScreenSize := Result.PhysicalScreenSize; if Result.PhysicalScreenSize.cx > 0 then Result.AspectRatio := Result.PhysicalScreenSize.cy / Result.PhysicalScreenSize.cx else Result.AspectRatio := 1; Result.PixelsPerInch := 96; // Windows Default Result.ScreenScale := 1; Result.FontScale := 1; end;
对比 Android 版本:
function TAndroidScreenServices.GetDisplayMetrics: TDeviceDisplayMetrics; var Metrics: JDisplayMetrics; RawScreenSize: JPoint; DensityDPI: Single; begin Metrics := TAndroidHelper.DisplayMetrics; if Metrics <> nil then begin Result.PhysicalScreenSize := TSize.Create(Metrics.widthPixels, Metrics.heightPixels); DensityDPI := Round((Metrics.xdpi + Metrics.ydpi) / 2); if DensityDPI <> 0 then begin Result.LogicalScreenSize.cx := Trunc(Metrics.widthPixels / DensityDPI); Result.LogicalScreenSize.cy := Trunc(Metrics.heightPixels / DensityDPI); end else Result.LogicalScreenSize := Result.PhysicalScreenSize; if Metrics.widthPixels <> 0 then Result.AspectRatio := Metrics.heightPixels / Metrics.widthPixels else Result.AspectRatio := 1; Result.PixelsPerInch := Round(DensityDPI); Result.ScreenScale := Metrics.density; Result.FontScale := Metrics.scaledDensity; end else Result := TDeviceDisplayMetrics.Default; RawScreenSize := MainActivity.getRawDisplaySize; if RawScreenSize <> nil then if (Result.PhysicalScreenSize.cx > Result.PhysicalScreenSize.cy) and (RawScreenSize.x > RawScreenSize.y) then Result.RawScreenSize := TSize.Create(RawScreenSize.x, RawScreenSize.y) else Result.RawScreenSize := TSize.Create(RawScreenSize.y, RawScreenSize.x) else Result.RawScreenSize := Result.PhysicalScreenSize; end;
再对比 iOS 的:
function TCocoaTouchScreenServices.GetDisplayMetrics: TDeviceDisplayMetrics; const IOSBasePPI = 163; var ScreenSize: TPointF; ScreenScale: Single; begin ScreenSize := GetScreenSize; ScreenScale := GetScreenScale; Result.PhysicalScreenSize := TSize.Create(Round(ScreenSize.X * ScreenScale), Round(ScreenSize.Y * ScreenScale)); Result.RawScreenSize := Result.PhysicalScreenSize; Result.LogicalScreenSize := TSize.Create(Round(ScreenSize.X), Round(ScreenSize.Y)); if Abs(ScreenSize.X) > 0 then Result.AspectRatio := ScreenSize.Y / ScreenSize.X else Result.AspectRatio := 1; Result.PixelsPerInch := Round(IOSBasePPI * ScreenScale); Result.ScreenScale := ScreenScale; Result.FontScale := ScreenScale; end;
换句话说,Windows 版的物理屏幕尺寸、逻辑屏幕尺寸和原始屏幕尺寸是一个东西,并不会反馈实际的显示器信息。要在 Windows 下获取屏幕的物理尺寸,可以调用 GetDeviceCaps 获取,索引为 HORZSIZE 和VERTSIZE,对应水平和垂直长度,单位为毫米。