如何重置PopupMenu的项目列表的最大宽度?

假设您在运行时向弹出菜单中添加了一些TMenuItem:

item1: [xxxxxxxxxxxxxxxxxxx]
item2: [xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx]


菜单会自动调整大小以适合最大的项目。
但是然后您执行Items.Clear并添加一个新项目:

item1: [xxxxxxxxxxxx                    ]


这样结束时,标题后留有很大的空白空间。

除了重新创建popupmenu之外,还有其他解决方法吗?

这里是重现此异常的代码:

procedure TForm1.Button1Click(Sender: TObject);
var
  t: TMenuItem;
begin
  t := TMenuItem.Create(PopupMenu1);
  t.Caption := 'largelargelargelargelargelarge';
  PopupMenu1.Items.Add(t);
  PopupMenu1.Popup(200, 200);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  t: TMenuItem;
begin
  PopupMenu1.Items.Clear;
  t := TMenuItem.Create(PopupMenu1);
  t.Caption := 'short';
  PopupMenu1.Items.Add(t);
  PopupMenu1.Popup(200, 200);
end;

最佳答案

tl,dr:附加一个ImageList。



如果菜单项可以发送WM_MEASUREITEM消息,则将重新计算宽度。

OwnerDraw属性设置为True可以实现这一点,这是第一个解决方案。但是,对于较旧的Delphi版本,这将导致菜单项的非默认绘制和非样式绘制。那是不可取的。

幸运的是,TMenu具有一种非凡的方式来判断菜单(项目)是否是所有者绘制的:

function TMenu.IsOwnerDraw: Boolean;
begin
  Result := OwnerDraw or (Images <> nil);
end;


因此,将Images属性设置为现有的ImageList将实现相同的效果。请注意,ImageList中不必有图像。并且如果其中包含图像,则不必使用它们,而将ImageIndex设为-1来显示菜单项。当然,带有图像的ImageList也可以。

关于delphi - TPopupMenu保留最大宽度,即使在Items.clear之后,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26435797/

10-09 19:42