- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
当表单类添加对运行时 DPI 切换的支持时,没有考虑菜单等基本 UI 元素。
菜单绘制从根本上被破坏,因为它依赖于 Screen.MenuFont,这是一个系统范围的指标,而不是特定于显示器。因此,虽然表单本身可以相对简单地正确缩放,但只有当缩放恰好与加载到 Screen 对象中的任何指标相匹配时,其上显示的菜单才能正常工作。
这是主菜单栏、其弹出菜单以及窗体上的所有弹出菜单的问题。如果将表单移动到具有与系统指标不同的 DPI 的监视器,则这些都不会缩放。
真正使这项工作有效的唯一方法是修复 VCL。等待 Embarcadero 充实多 DPI 并不是一个真正的选择。
查看 VCL 代码,基本问题是 Screen.MenuFont 属性被分配给菜单 Canvas ,而不是选择适合显示菜单的监视器的字体。只需在 VCL 源代码中搜索 Screen.MenuFont 即可找到受影响的类。
无需完全重写所涉及的类,解决此限制的正确方法是什么?
我的第一个倾向是使用迂回方式来跟踪菜单弹出窗口,并在使用 Screen.MenuFont 属性设置菜单时覆盖该属性。这看起来太过分了。
最佳答案
这是一种目前有效的解决方案。使用Delphi Detours Library ,将此单元添加到 dpr 使用列表(我必须在其他表单之前将其放在列表顶部附近)会导致根据在任何弹出窗口中保存菜单项的表单,将正确的字体大小应用于菜单 Canvas 菜单。该解决方案故意忽略顶级菜单(主菜单栏),因为 VCL 无法正确处理那里的所有者测量的项目。
unit slMenuDPIFix;
// add this unit to the main application dpr file BEFORE ANY FORMS in the uses list.
interface
implementation
uses
Winapi.Windows, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Menus, slScaleUtils, Math,
DDetours;
type
TMenuClass = class(TMenu);
TMenuItemClass = class(TMenuItem);
var
TrampolineMenuCreate: procedure(const Self: TMenuClass; AOwner: TComponent) = nil;
TrampolineMenuItemAdvancedDrawItem: procedure(const Self: TMenuItemClass; ACanvas: TCanvas; ARect: TRect; State: TOwnerDrawState; TopLevel: Boolean) = nil;
TrampolineMenuItemMeasureItem: procedure(const Self: TMenuItemClass; ACanvas: TCanvas; var Width, Height: Integer) = nil;
function GetPopupDPI(const MenuItem: TMenuItemClass): Integer;
var
pm: TMenu;
pcf: TCustomForm;
begin
Result := Screen.PixelsPerInch;
pm := MenuItem.GetParentMenu;
if Assigned(pm) and (pm.Owner is TControl) then
pcf := GetParentForm(TControl(pm.Owner))
else
pcf := nil;
if Assigned(pcf) and (pcf is TForm) then
Result := TForm(pcf).PixelsPerInch;
end;
procedure MenuCreateHooked(const Self: TMenuClass; AOwner: TComponent);
begin
TrampolineMenuCreate(Self, AOwner);
Self.OwnerDraw := True; // force always ownerdraw.
end;
procedure MenuItemAdvancedDrawItemHooked(const Self: TMenuItemClass; ACanvas: TCanvas; ARect: TRect; State: TOwnerDrawState; TopLevel: Boolean);
begin
if (not TopLevel) then
begin
ACanvas.Font.Height := MulDiv(ACanvas.Font.Height, GetPopupDPI(Self), Screen.PixelsPerInch);
end;
TrampolineMenuItemAdvancedDrawItem(Self, ACanvas, ARect, State, TopLevel);
end;
procedure MenuItemMeasureItemHooked(const Self: TMenuItemClass; ACanvas: TCanvas; var Width, Height: Integer);
var
lHeight: Integer;
pdpi: Integer;
begin
pdpi := GetPopupDPI(Self);
if (Self.Caption <> cLineCaption) and (pdpi <> Screen.PixelsPerInch) then
begin
ACanvas.Font.Height := MulDiv(ACanvas.Font.Height, pdpi, Screen.PixelsPerInch);
lHeight := ACanvas.TextHeight('|') + MulDiv(6, pdpi, Screen.PixelsPerInch);
end else
lHeight := 0;
TrampolineMenuItemMeasureItem(Self, ACanvas, Width, Height);
if lHeight > 0 then
Height := Max(Height, lHeight);
end;
initialization
TrampolineMenuCreate := InterceptCreate(@TMenuClass.Create, @MenuCreateHooked);
TrampolineMenuItemAdvancedDrawItem := InterceptCreate(@TMenuItemClass.AdvancedDrawItem, @MenuItemAdvancedDrawItemHooked);
TrampolineMenuItemMeasureItem := InterceptCreate(@TMenuItemClass.MeasureItem, @MenuItemMeasureItemHooked);
finalization
InterceptRemove(@TrampolineMenuCreate);
InterceptRemove(@TrampolineMenuItemAdvancedDrawItem);
InterceptRemove(@TrampolineMenuItemMeasureItem);
end.
人们可以轻松地修补 Vcl.Menus,但我不想这样做。
关于delphi - Delphi Seattle 中运行时 DPI 更改后如何处理菜单缩放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33020096/
我 Handlebars 机图片尺寸调整为731*974,但还是有920KB。所以我想将图像分辨率从96dpi更改为72dpi(因为我发现iPhone中的图片是72dpi,看起来不错)。任何人都可以提
我制作了这个非常简单的计算器布局。但是我手机上的 480 DPI 和 420 DPI 是不同的。 420DPI 屏幕右侧有空闲空间,按钮比 480DPI 更细。我使用 dp 作为按钮的测量单位,sp
使用 phantomjs ,有没有办法控制使用 page.render(filename) 光栅化 Web 内容的图像时使用的 DPI 设置?方法? 我找不到任何可以通过 the interface
众所周知,Windows 7 可用的 DPI 缩放比例为 100%、125%、150% 和 200%。这四个DPI百分比的实际DPI值是 Percentage - DPI Values 100%
我试图找到 WinMerge 的替代方案来解决 150% DPI 下的文本模糊问题。虽然我的问题被关闭了(我认为这种心态没有帮助),但我找到了答案所以我分享它。 最佳答案 您可以继续使用 WinMer
我有一些我想打印出来的图像。这些图像可以采用不同的格式,从不同的 DPI 到不同的格式(JPEG、PNG 等) 现在我所做的是将图像加载到我的应用程序中并尝试 将 dpi 转换为 96。但是在这个过程
DPI 和 PPI 有什么区别吗?是这样吗:点 = 像素?最后,C#.net 中的 DpiX 和 DpiY 是什么?我们如何改变它们? 最佳答案 新闻部 代表每英寸点数,在打印时使用。它也被严重滥用于
我有一个可视化代码,例如: for cluster in ready_couples_2.cluster.unique(): sns.set(rc={'figure.figsize':(11.
我正在努力优化我的网络应用程序中的滚动性能,并在最新的 Chrome (v31) 上遇到了有趣的行为,该行为也在 Chrome Canary (v34) 上重现。 在这个简化的示例中,我有一个简单的可
我正在构建一个具有 hdpi 分辨率图形 Assets 的游戏(因此我将文件放在 drawable-hdpi 目录中)。我不希望图像具有相应的 mdpi 分辨率,我将在基于 240-dpi 的像素坐标
我必须重新布局一个非常复杂的 UI,因为我们发现它在高 dpi 系统上基本上不可用。这是因为为了在 Qt Creator 中获得我们想要的布局设计,我们对几乎所有内容都使用了固定大小。 我的问题是,如
我的系统上安装了 Win 8.1 系统。我曾经根据我的 WPF 应用程序 (Win 7) 中的以下内容计算 DPI: Matrix m = PresentationSource.FromVisual(
我有一个使用 Substance LookAndFeel 的 Java 应用程序,Windows 作为目标平台,我想增加我的应用程序的 DPI 设置, 不更改系统设置。 我想这样做是因为我不想强制用户
我有一个非常奇怪的问题......在我的 iPhone 应用程序中,用户可以打开相机胶卷中的图像,在我的示例中 1920 x 1080 像素 (72 dpi) 的壁纸。 现在,想要将图像的宽度调整为例
我遇到一个问题,应用程序(用 Delphi 编写)在所有系统上的默认 96 DPI 设置下表现正常,但在不同系统上的“150% 文本大小”(内部 144 dpi)设置下表现不一致。似乎在某些系统上,我
我看过官方Qt documentation以及 StackOverflow 上关于 Qt 中高 DPI 支持的许多文章和问题。他们都专注于移植旧的应用程序并让它们以尽可能少的更改工作。 但是,如果我要
在matplotlib中,我使用LineCollection绘制国家/地区的颜色,并指定了县/市的边界。当我将图形另存为pdf文件时: fig.savefig('filename.pdf',dpi=3
我想以编程方式确定用户显示器的 DPI,以便以精确的单位数(厘米/英寸)显示网页。我知道这是一个奇怪的要求:它是针对一个可视化研究项目的,它是一种控制。我们目前通过让用户将信用卡放在屏幕上并将可调整大
我使用 matplotlib 创建了一个图形,但我已经意识到绘图轴和绘制的线被缩小了。 阅读本文 earlier discussion thread ,它解释了如何设置图形大小。 fig, ax =
晚安,我正在与一些合作伙伴使用 javaFx 制作一个应用程序;我们的想法是它将在 Windows 和 Linux 中使用。我们进行了一些测试,发现应用程序在两种操作系统中的显示有所不同。 我们正在使
我是一名优秀的程序员,十分优秀!