【问题标题】:Resizing main menu for high DPI/font size为高 DPI/字体大小调整主菜单
【发布时间】:2013-12-29 12:50:24
【问题描述】:

当标准主菜单/弹出菜单包含图像时,我的字体高度存在问题。看起来像这样。

当没有图像时,没有如上所示的问题。主菜单使用TImageList,图像宽度/高度设置为16。

所以我想将图像尺寸保持在 16x16 并将其居中,以获得如下效果:

如何读取主菜单的字体高度并相应地调整TImageList 中的图像?我的一个想法是将图像从一个TImageList 复制到另一个具有更大图像宽度/高度的图像,但我仍然需要根据字体大小确定合适的大小。我该怎么做?

更新

我通过检查SystemParametersInfo - SPI_GETNONCLIENTMETRICS 值并使用iMenuHeight 值作为TImageList 宽度/高度解决了这个问题。由于更改宽度/高度后图像被删除,我将另一个复制到另一个TImageList。完全按照应有的方式工作。感谢大家提供最有帮助的答案。

更新 2

在进一步检查问题后,我标记为正确的解决方案提供了更好的结果,所以我改用那个解决方案。在 Win7 和 XP 上测试,似乎工作正常。

【问题讨论】:

  • 哪个 Delphi 版本?哪个操作系统?坦率地说,德尔福 RTL 菜单代码很烂。在 XP 上可以工作,但在 Vista+ 上无望。我总是在 Vista+ 上用我自己的代码替换它,让系统绘制菜单,所以它是正确的。
  • 我使用的是 2010 版本,操作系统是……所有这些。 XP、Vista、Win7 和 8。我已经可以通过调整图像大小来解决上述问题,但我很可能需要确定菜单使用的字体大小的方法。

标签: delphi user-interface fonts c++builder dpi


【解决方案1】:

Screen.MenuFont的高度可以通过选择到一个临时DC来获得:

function GetMenuFontHeight: Integer;
var
  DC: HDC;
  SaveObj: HGDIOBJ;
  Size: TSize;
begin
  DC := GetDC(HWND_DESKTOP);
  try
    SaveObj := SelectObject(DC, Screen.MenuFont.Handle);
    GetTextExtentPoint32(DC, '|', 1, Size); // the character doesn't really matter
    Result := Size.cy;
    SelectObject(DC, SaveObj);
  finally
    ReleaseDC(HWND_DESKTOP, DC);
  end;
end;

【讨论】:

  • 这对 XP 和 Windows Classic 来说很好,但与主题菜单无关。我想。
  • @David - 这就是 VCL 用作菜单字体的内容。我认为.. 编辑:我可以验证设置 Screen.FontMenu 的字体名称,菜单外观发生变化(W7 aero)。
  • 不适用于主题菜单,Vista+。它使用主题 API。尽管 Delphi RTL 在您拥有图像时会愚蠢地进行用户绘制并以许多不同的方式将其搞砸。而不是做明智的事情并让系统绘制菜单。
  • AFAIK,最佳测量字符串是'Wy'
  • @Free - 真的没关系(你可以测试'.')。因为我已经在 W2K 上实现了它,所以我在每个操作系统上都对其进行了测试(还不是 W8)。
【解决方案2】:

嗯,Canvas.GetTextHeight('gh') 通常有助于获得文本的高度。但在不同 DPI 的情况下,您可以简单地按Screen.PixelsPerInch / 96.0 缩放。

【讨论】:

  • 感谢您的回答,但它不会返回为 Windows 中的菜单项设置的字体大小,而是返回表单标签上使用的字体。在这种情况下,它返回 16,但应该返回 24 左右。
【解决方案3】:

文本高度可能不是您需要使用的。我建议您使用方形尺寸等于流行的小图标大小的图标。这是 ID 为 SM_CXSMICON 的系统指标。通过调用 GetSystemMetrics 并传递该 ID 来检索值。

【讨论】:

  • 在 windows 中设置自定义菜单字体不会影响小图标的大小。
  • @SertacAkyuz 不,它没有。这涉及 DPI 设置。可能还需要HIGHDPIAWARE。如果用户在 XP 中选择了较大的菜单字体大小,那么您确实需要修复损坏的 Delphi VCL 菜单代码。
  • 我通过使用 SystemParametersInfo 中的SPI_GETNONCLIENTMETRICS 并使用iMenuHeight 值并将其放入 TImageList 高度/宽度(并在其中复制 16x16 图像)来解决它。为我提供每个菜单项应有的完美高度。
  • @Coder12345 这不太可能与主题 Vista+ 菜单 IIRC 相关
【解决方案4】:

您可以使用具有许多高级功能的电源菜单组件 从这里下载:http://elvand.com/downloads/DELPHI/PowerMenu.zip

Delphi7-XE2 大小=193 KB

【讨论】:

  • 谢谢,但我并不是真的在寻找主菜单的替换组件。标准主菜单工作正常。
  • 它是否适用于 Delphi XE4?它有哪些特点?
【解决方案5】:
 #include <windows.h>

 int GetMainMenuHeight(void)
 {
   NONCLIENTMETRICS Rec;

   Rec.cbSize = sizeof(Rec);
   if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, Rec.cbSize, &Rec.cbSize, 0))
    return Rec.iMenuHeight;
   else return -1;
 }

【讨论】:

  • 您能否解释一下您显示的代码的作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多