首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在运行时快速更新TMainMenu项?

如何在运行时快速更新TMainMenu项?
EN

Stack Overflow用户
提问于 2022-08-08 16:25:15
回答 1查看 105关注 0票数 1

下面的代码演示了这个问题。它更新一些菜单项的文本。FormActivate函数在我的笔记本上需要超过半秒的时间。菜单项越多,时间就越长,尤其是当菜单项有图像的时候。这大大增加了我的应用程序的启动时间。我已经使用TForm.BeginUpdate试图阻止更新,直到所有的完成,但这似乎只是一点帮助。运行Windows 32位.

注意,在我的示例中有两种类型的菜单项。我正在更新的和我没有更新的。我正在更新的那些没有图像。是那些我没有更新的图片的存在使它变慢了。由此,我必须假设,每次更新一个菜单项时,整个菜单都会被更新和重新绘制。似乎缺少的是TMainMenu.BeginUpdate和TMainMenu.EndUpdate。

编辑:我在FMX.Platform.Menu.Win过程TWinMenuService.UpdateMenuItem中找到了以下评论。

代码语言:javascript
运行
复制
// If Visible, Text or Shortcut are changed, then we need to rebuild menu. Because WinApi doesn't support
RecreateMainMenu(MenuItem);

表格:

代码语言:javascript
运行
复制
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

单位:

代码语言:javascript
运行
复制
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.
EN

回答 1

Stack Overflow用户

发布于 2022-08-09 11:14:52

我现在已经找到了解决这个问题的方法,尽管它使用了可怕的攻击来设置私有变量。运行时现在大约是50 is。如果有什么好的理由我不应该这么做的话请告诉我?我看到的主要缺点是,今后对Delphi的更新可能会破坏它。

代码语言:javascript
运行
复制
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.
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73281150

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档