下面的代码演示了这个问题。它更新一些菜单项的文本。FormActivate函数在我的笔记本上需要超过半秒的时间。菜单项越多,时间就越长,尤其是当菜单项有图像的时候。这大大增加了我的应用程序的启动时间。我已经使用TForm.BeginUpdate试图阻止更新,直到所有的完成,但这似乎只是一点帮助。运行Windows 32位.
注意,在我的示例中有两种类型的菜单项。我正在更新的和我没有更新的。我正在更新的那些没有图像。是那些我没有更新的图片的存在使它变慢了。由此,我必须假设,每次更新一个菜单项时,整个菜单都会被更新和重新绘制。似乎缺少的是TMainMenu.BeginUpdate和TMainMenu.EndUpdate。
编辑:我在FMX.Platform.Menu.Win过程TWinMenuService.UpdateMenuItem中找到了以下评论。
// If Visible, Text or Shortcut are changed, then we need to rebuild menu. Because WinApi doesn't support
RecreateMainMenu(MenuItem);
表格:
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 480
ClientWidth = 640
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
OnActivate = FormActivate
OnCreate = FormCreate
DesignerMasterStyle = 0
object MainMenu1: TMainMenu
Images = ImageList1
Left = 32
Top = 40
object MenuItem1: TMenuItem
Text = 'File'
object MenuItem22: TMenuItem
Locked = True
Text = 'Recent Files'
object MenuItem2: TMenuItem
Locked = True
Text = 'Recent File'
end
object MenuItem3: TMenuItem
Locked = True
Text = 'Recent File'
end
object MenuItem4: TMenuItem
Locked = True
Text = 'Recent File'
end
object MenuItem5: TMenuItem
Locked = True
Text = 'Recent File'
end
object MenuItem6: TMenuItem
Locked = True
Text = 'Recent File'
end
object MenuItem7: TMenuItem
Locked = True
Text = 'Recent File'
end
object MenuItem8: TMenuItem
Locked = True
Text = 'Recent File'
end
object MenuItem9: TMenuItem
Locked = True
Text = 'Recent File'
end
object MenuItem10: TMenuItem
Locked = True
Text = 'Recent File'
end
object MenuItem11: TMenuItem
Locked = True
Text = 'Recent File'
end
object MenuItem12: TMenuItem
Locked = True
Text = 'Recent File'
end
object MenuItem13: TMenuItem
Locked = True
Text = 'Recent File'
end
object MenuItem14: TMenuItem
Locked = True
Text = 'Recent File'
end
object MenuItem15: TMenuItem
Locked = True
Text = 'Recent File'
end
object MenuItem16: TMenuItem
Locked = True
Text = 'Recent File'
end
object MenuItem17: TMenuItem
Locked = True
Text = 'Recent File'
end
object MenuItem18: TMenuItem
Locked = True
Text = 'Recent File'
end
object MenuItem19: TMenuItem
Locked = True
Text = 'Recent File'
end
object MenuItem20: TMenuItem
Locked = True
Text = 'Recent File'
end
object MenuItem21: TMenuItem
Locked = True
Text = 'Recent File'
end
end
object MenuItem33: TMenuItem
Locked = True
Text = 'MenuItem33'
ImageIndex = 0
end
object MenuItem32: TMenuItem
Locked = True
Text = 'MenuItem32'
ImageIndex = 0
end
object MenuItem31: TMenuItem
Locked = True
Text = 'MenuItem31'
ImageIndex = 0
end
object MenuItem30: TMenuItem
Locked = True
Text = 'MenuItem30'
ImageIndex = 0
end
object MenuItem29: TMenuItem
Locked = True
Text = 'MenuItem29'
ImageIndex = 0
end
object MenuItem28: TMenuItem
Locked = True
Text = 'MenuItem28'
ImageIndex = 0
end
object MenuItem27: TMenuItem
Locked = True
Text = 'MenuItem27'
ImageIndex = 0
end
object MenuItem26: TMenuItem
Locked = True
Text = 'MenuItem26'
ImageIndex = 0
end
object MenuItem25: TMenuItem
Locked = True
Text = 'MenuItem25'
ImageIndex = 0
end
object MenuItem24: TMenuItem
Locked = True
Text = 'MenuItem24'
ImageIndex = 0
end
object MenuItem23: TMenuItem
Locked = True
Text = 'MenuItem23'
ImageIndex = 0
end
object MenuItem34: TMenuItem
Locked = True
Text = 'MenuItem34'
ImageIndex = 0
end
object MenuItem35: TMenuItem
Locked = True
Text = 'MenuItem35'
ImageIndex = 0
end
object MenuItem36: TMenuItem
Locked = True
Text = 'MenuItem36'
ImageIndex = 0
end
object MenuItem37: TMenuItem
Locked = True
Text = 'MenuItem37'
ImageIndex = 0
end
end
object MenuItem38: TMenuItem
Text = 'MenuItem38'
object MenuItem39: TMenuItem
Locked = True
Text = 'MenuItem23'
ImageIndex = 0
end
object MenuItem40: TMenuItem
Locked = True
Text = 'MenuItem24'
ImageIndex = 0
end
object MenuItem41: TMenuItem
Locked = True
Text = 'MenuItem25'
ImageIndex = 0
end
object MenuItem42: TMenuItem
Locked = True
Text = 'MenuItem26'
ImageIndex = 0
end
object MenuItem43: TMenuItem
Locked = True
Text = 'MenuItem27'
ImageIndex = 0
end
object MenuItem44: TMenuItem
Locked = True
Text = 'MenuItem28'
ImageIndex = 0
end
object MenuItem45: TMenuItem
Locked = True
Text = 'MenuItem29'
ImageIndex = 0
end
object MenuItem46: TMenuItem
Locked = True
Text = 'MenuItem30'
ImageIndex = 0
end
object MenuItem47: TMenuItem
Locked = True
Text = 'MenuItem31'
ImageIndex = 0
end
object MenuItem48: TMenuItem
Locked = True
Text = 'MenuItem32'
ImageIndex = 0
end
object MenuItem49: TMenuItem
Locked = True
Text = 'MenuItem33'
ImageIndex = 0
end
object MenuItem50: TMenuItem
Locked = True
Text = 'MenuItem34'
ImageIndex = 0
end
object MenuItem51: TMenuItem
Locked = True
Text = 'MenuItem35'
ImageIndex = 0
end
object MenuItem52: TMenuItem
Locked = True
Text = 'MenuItem36'
ImageIndex = 0
end
object MenuItem53: TMenuItem
Locked = True
Text = 'MenuItem37'
ImageIndex = 0
end
end
end
object ImageList1: TImageList
Source = <
item
MultiResBitmap.LoadSize = 0
MultiResBitmap = <
item
Width = 16
Height = 16
PNG = {
89504E470D0A1A0A0000000D49484452000000100000001008060000001FF3FF
61000000017352474200AECE1CE90000000467414D410000B18F0BFC61050000
032949444154384F5D934B685C551CC67FF79E7BEFBC3BEF4CD3249369A32636
B6962A68C5E24221561A176E44ECC285F52D2E447421C58D0B11379A45A156A4
8A101485162D546335D08598D6C6A41AA3A6339D4CF39874DA6492CE64E69E7B
BD270C68FCE0700EE7FFFDBEF3E01C8DFF69E2A43D756A489B397E6646BA64EB
A0B950F23F3D9035065F7477EC7AD4E86B5937B429E0A5841CFEB28D68EE39B7
379A231200296AC8D5066E65817AF1236DFAB14556862AE2F116F26F403F856F
52473A72771CA4B3BD4CF54006BD238195CA34E30BF366E5F309562F2645ECAF
B372EEFA91D2E54B743FA2B88D80C3B7C9538BCFB8BDFD0F93CD9F66E6C461D9
23A296A56AFFD55B1FC8DF6FDC47B630CA5CFAA836756C5A0CEA63DFDA57266F
77E37B06C9FDF21BAB3F2F237E1815A5F18BB27CE86D79696858FEBD5E935205
0CDC4D4CC1997B68578C62B5375EB07FAA1FA07B566035D6B04D89737D92F2B5
2081543FE92BA314475EA6ABAB5B6C999C94E5E3799C8DED78F29FA6A0FF3821
6AB50461BF8DBB35846E8531B49D6CF36F2779EE3B160705EB0A069777BFA2DC
62518C62F57A501A8910462C8096AFE25E28D22C9469CC2E504BE7A9BCF78EB6
5701CFBEE9FCFA4911F187147E05AB39C5EAE1ED840316DAD82CF26A154216E6
B64E82F35354875F230B3A5F7C2FAF1E9BC7B76F80F6D2A2B4C7A7A92D398850
1761DDF01CE3D770BC819ED9828847D0A523DCBDB7E2DBB98B985AE9B3332CF7
DE4F9B7A17A918BAF2AA79D3EBB5D78FDAF9F31D248202DD6922BDA322C288A5
3C6BE747980F87D1434902BB1F204303C72BA39B889BDE65DF55A2A21FBC57C4
EA73ACC5E29866106146BCA6A3359AD81F3E4FC7C957C9F56509AC7BABF92318
860F5D7915A3587DFF1E2DB6A346A3D140C6A31841036DA58EB3DB0F4FEE17C9
7DBD22FCF513EB69B78EED33D112094CE5558C6237CE72E215A37B6E8C25E9E0
A4DAB0B626318B1AE2C68A6CAAFAFB177C55159E4C612A8FF22A46D5367DA6A7
3EB51796A2F87B7A0854BDE752F8936AC412A2EE97D62D19ACFC65D652CBD43F
3E64645AC8E600A59129FBE6D959D1182B4B5BF379DBF56ECDD7A079671AF3A1
4ECC07FB8C60CBEA09FE01BAF244AA6BA3EA9D0000000049454E44AE426082}
FileName = 'about.png'
end>
Name = 'about'
end>
Destination = <
item
Layers = <
item
Name = 'about'
end>
end>
Left = 104
Top = 40
end
end
单位:
unit Unit1;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Menus,
System.ImageList, FMX.ImgList;
type
TForm1 = class(TForm)
MainMenu1: TMainMenu;
MenuItem1: TMenuItem;
MenuItem2: TMenuItem;
MenuItem3: TMenuItem;
MenuItem4: TMenuItem;
MenuItem5: TMenuItem;
MenuItem6: TMenuItem;
MenuItem7: TMenuItem;
MenuItem8: TMenuItem;
MenuItem9: TMenuItem;
MenuItem10: TMenuItem;
MenuItem11: TMenuItem;
MenuItem12: TMenuItem;
MenuItem13: TMenuItem;
MenuItem14: TMenuItem;
MenuItem15: TMenuItem;
MenuItem16: TMenuItem;
MenuItem17: TMenuItem;
MenuItem18: TMenuItem;
MenuItem19: TMenuItem;
MenuItem20: TMenuItem;
MenuItem21: TMenuItem;
MenuItem22: TMenuItem;
MenuItem23: TMenuItem;
MenuItem24: TMenuItem;
MenuItem25: TMenuItem;
MenuItem26: TMenuItem;
MenuItem27: TMenuItem;
MenuItem28: TMenuItem;
MenuItem29: TMenuItem;
MenuItem30: TMenuItem;
MenuItem31: TMenuItem;
MenuItem32: TMenuItem;
MenuItem33: TMenuItem;
ImageList1: TImageList;
MenuItem34: TMenuItem;
MenuItem35: TMenuItem;
MenuItem36: TMenuItem;
MenuItem37: TMenuItem;
MenuItem38: TMenuItem;
MenuItem39: TMenuItem;
MenuItem40: TMenuItem;
MenuItem41: TMenuItem;
MenuItem42: TMenuItem;
MenuItem43: TMenuItem;
MenuItem44: TMenuItem;
MenuItem45: TMenuItem;
MenuItem46: TMenuItem;
MenuItem47: TMenuItem;
MenuItem48: TMenuItem;
MenuItem49: TMenuItem;
MenuItem50: TMenuItem;
MenuItem51: TMenuItem;
MenuItem52: TMenuItem;
MenuItem53: TMenuItem;
procedure FormCreate(Sender: TObject);
procedure FormActivate(Sender: TObject);
private
{ Private declarations }
RecentFileItems : array[0..19] of TMenuItem;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.fmx}
procedure TForm1.FormCreate(Sender: TObject);
var
i : Integer;
begin
// Assign menu items to array
RecentFileItems[0] := MenuItem2;
RecentFileItems[1] := MenuItem3;
RecentFileItems[2] := MenuItem4;
RecentFileItems[3] := MenuItem5;
RecentFileItems[4] := MenuItem6;
RecentFileItems[5] := MenuItem7;
RecentFileItems[6] := MenuItem8;
RecentFileItems[7] := MenuItem9;
RecentFileItems[8] := MenuItem10;
RecentFileItems[9] := MenuItem11;
RecentFileItems[10] := MenuItem12;
RecentFileItems[11] := MenuItem13;
RecentFileItems[12] := MenuItem14;
RecentFileItems[13] := MenuItem15;
RecentFileItems[14] := MenuItem16;
RecentFileItems[15] := MenuItem17;
RecentFileItems[16] := MenuItem18;
RecentFileItems[17] := MenuItem19;
RecentFileItems[18] := MenuItem20;
RecentFileItems[19] := MenuItem21;
end;
procedure TForm1.FormActivate(Sender: TObject);
var
i : Integer;
st : TDateTime;
begin
st := now;
BeginUpdate; // Reduces runtime only slightly
try
for i := 0 to 19 do
RecentFileItems[i].Text := 'Recent File Name ' + IntToStr(i);
finally
EndUpdate;
end;
// Display the time this function took in ms
// Time increases significantly if there are many other menu items with images
Caption := IntToStr(Round((now - st)*24*3600*1000));
end;
end.
发布于 2022-08-09 11:14:52
我现在已经找到了解决这个问题的方法,尽管它使用了可怕的攻击来设置私有变量。运行时现在大约是50 is。如果有什么好的理由我不应该这么做的话请告诉我?我看到的主要缺点是,今后对Delphi的更新可能会破坏它。
unit Unit1;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Menus,
System.ImageList, FMX.ImgList;
type
TForm1 = class(TForm)
MainMenu1: TMainMenu;
MenuItem1: TMenuItem;
MenuItem2: TMenuItem;
MenuItem3: TMenuItem;
MenuItem4: TMenuItem;
MenuItem5: TMenuItem;
MenuItem6: TMenuItem;
MenuItem7: TMenuItem;
MenuItem8: TMenuItem;
MenuItem9: TMenuItem;
MenuItem10: TMenuItem;
MenuItem11: TMenuItem;
MenuItem12: TMenuItem;
MenuItem13: TMenuItem;
MenuItem14: TMenuItem;
MenuItem15: TMenuItem;
MenuItem16: TMenuItem;
MenuItem17: TMenuItem;
MenuItem18: TMenuItem;
MenuItem19: TMenuItem;
MenuItem20: TMenuItem;
MenuItem21: TMenuItem;
MenuItem22: TMenuItem;
MenuItem23: TMenuItem;
MenuItem24: TMenuItem;
MenuItem25: TMenuItem;
MenuItem26: TMenuItem;
MenuItem27: TMenuItem;
MenuItem28: TMenuItem;
MenuItem29: TMenuItem;
MenuItem30: TMenuItem;
MenuItem31: TMenuItem;
MenuItem32: TMenuItem;
MenuItem33: TMenuItem;
ImageList1: TImageList;
MenuItem34: TMenuItem;
MenuItem35: TMenuItem;
MenuItem36: TMenuItem;
MenuItem37: TMenuItem;
MenuItem38: TMenuItem;
MenuItem39: TMenuItem;
MenuItem40: TMenuItem;
MenuItem41: TMenuItem;
MenuItem42: TMenuItem;
MenuItem43: TMenuItem;
MenuItem44: TMenuItem;
MenuItem45: TMenuItem;
MenuItem46: TMenuItem;
MenuItem47: TMenuItem;
MenuItem48: TMenuItem;
MenuItem49: TMenuItem;
MenuItem50: TMenuItem;
MenuItem51: TMenuItem;
MenuItem52: TMenuItem;
MenuItem53: TMenuItem;
procedure FormCreate(Sender: TObject);
procedure FormActivate(Sender: TObject);
private
{ Private declarations }
RecentFileItems : array[0..19] of TMenuItem;
public
{ Public declarations }
end;
// Hack class to be able to set private FText field of TTextControl
TTextControlHack = class(TStyledControl)
public
FTextSettingsInfo: TTextSettingsInfo;
FTextObject: TControl;
FITextSettings: ITextSettings;
FObjectState: IObjectState;
FText: string;
end;
var
Form1: TForm1;
implementation
{$R *.fmx}
procedure TForm1.FormCreate(Sender: TObject);
begin
// Assign menu items to array
RecentFileItems[0] := MenuItem2;
RecentFileItems[1] := MenuItem3;
RecentFileItems[2] := MenuItem4;
RecentFileItems[3] := MenuItem5;
RecentFileItems[4] := MenuItem6;
RecentFileItems[5] := MenuItem7;
RecentFileItems[6] := MenuItem8;
RecentFileItems[7] := MenuItem9;
RecentFileItems[8] := MenuItem10;
RecentFileItems[9] := MenuItem11;
RecentFileItems[10] := MenuItem12;
RecentFileItems[11] := MenuItem13;
RecentFileItems[12] := MenuItem14;
RecentFileItems[13] := MenuItem15;
RecentFileItems[14] := MenuItem16;
RecentFileItems[15] := MenuItem17;
RecentFileItems[16] := MenuItem18;
RecentFileItems[17] := MenuItem19;
RecentFileItems[18] := MenuItem20;
RecentFileItems[19] := MenuItem21;
end;
procedure TForm1.FormActivate(Sender: TObject);
var
i : Integer;
st : TDateTime;
begin
st := now;
BeginUpdate; // Reduces runtime only slightly
try
for i := 0 to 18 do
//RecentFileItems[i].Text := 'Recent File Name ' + IntToStr(i);
// Hack the private FText field of TTextControl to prevent update
TTextControlHack(RecentFileItems[i]).FText := 'Recent File Name ' + IntToStr(i);
// Now set the final menu item normally to update the whole menu. Make sure that the value is actually changed
i := 19;
RecentFileItems[i].Text := 'Recent File Name ' + IntToStr(i);
finally
EndUpdate;
end;
// Display the time this function took in ms
Caption := IntToStr(Round((now - st)*24*3600*1000));
end;
end.
https://stackoverflow.com/questions/73281150
复制相似问题