ActionMainMenuBar带有32x32图标

时间:2013-07-04 13:59:11

标签: delphi action-menu

Delphi Xe4。表单,ActionManager,ImageList(带有32x32图标),ActionMainMenuBar。

我无法确保图标正确显示。你该怎么办?

Pic1

同时,如果我应用任何vcl风格的装饰,它显示正常。但是,如果默认情况下为“Windows”样式,则文本会移出图标。帮助

Pic2

Pic3

Pic4

抱歉英语不好。

1 个答案:

答案 0 :(得分:6)

这是一个有效的问题,TActionMainMenuBar旨在设计为能够将自定义图标大小处理为菜单图像,就像本机菜单可以很好地处理它们一样。可以在代码中的注释中找到对此的一个指示,f.i。在下面的VCL代码中,您可以找到评论16 is standard image size so adjust for larger images

我认为,错误的代码位于'ActnMenus.pas'的TCustomMenuItem.CalcBounds中。以下摘录自D2007。请注意下面的行我用一些感叹号评论。在上升课程TCustomActionControl计算文本和图片在CalcLayout方法中的位置后,TCustomMenuItem会在上述声明中使用硬编码 24 对其进行废弃处理点。

procedure TCustomMenuItem.CalcBounds;
var
  AWidth, AHeight: Integer;
  NewTextBounds: TRect;
  ImageSize: TPoint;
  ImageOffset: Integer;
begin
  inherited CalcBounds;
  ImageSize := GetImageSize;
  AHeight := FCYMenu;
  if Separator then
    AHeight := FCYMenu div 3 * 2
  else
    // 16 is standard image size so adjust for larger images
    if ImageSize.Y > 16 then
      AHeight := ImageSize.Y + 4;
  if ActionClient = nil then exit;
  if ImageSize.X <= 16 then
    ImageOffset := 24
  else
    ImageOffset := ImageSize.X + 6;  // Leave room for an image frame
  NewTextBounds := TextBounds;
  OffsetRect(NewTextBounds, 24 - TextBounds.Left,          // <- !!!!!
    AHeight div 2 - TextBounds.Bottom div 2 - 1);
  TextBounds := NewTextBounds;
  ShortCutBounds := Rect(0,0,0,0);
  if ActionClient.ShortCut <> 0 then
  begin
    Windows.DrawText(Canvas.Handle, PChar(ActionClient.ShortCutText), -1,
      FShortCutBounds, DT_CALCRECT);
    // Left offset is determined when the item is painted to make it right justified
    FShortCutBounds.Top := TextBounds.Top;
    FShortCutBounds.Bottom := TextBounds.Bottom;
    AWidth := TextBounds.Right + FShortCutBounds.Right + ImageOffset + Spacing;
  end
  else
    AWidth := TextBounds.Right + TextBounds.Left;
  SetBounds(Left, Top, AWidth, AHeight);
end;
24 是基于具有16个或更少像素宽度的图像的假设。应该使用的是ImageOffset值,仅计算上面几行。取代

  OffsetRect(NewTextBounds, 24 - TextBounds.Left,
    AHeight div 2 - TextBounds.Bottom div 2 - 1);

  OffsetRect(NewTextBounds, ImageOffset - TextBounds.Left,
    AHeight div 2 - TextBounds.Bottom div 2 - 1);

你会有这样的事情:

dropped menu

你会注意到其他一些奇怪的东西,没有图像的物品仍然可以用于小图像布局。 IMO所有菜单项应具有相同的基本布局,但操作菜单的设计允许单个项目的不同布局。另一个奇怪的事情是带有图像的项目的已检查状态('Action6'),虽然我不确定我是否错过了这里的设置或者是否有资格作为错误