上官方的实现源码:
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,对应水平和垂直长度,单位为毫米。
