zoukankan      html  css  js  c++  java
  • Delphi编程中动态菜单要点归纳

     

    一、创建菜单并添加项目
      在设计程序时,有时需要动态创建菜单, 通常使用以下的语句:

      PopupMenu1 := TPopupMenu.Create(Self);
      Item := TMenuItem.Create(PopupMenu1);
      Item.Caption := '菜单一';
      Item.OnClick := MenuItem1Click;
      PopupMenu1.Items.Add(Item);
      Item := TMenuItem.Create(PopupMenu1);
      Item.Caption := '菜单二';
      Item.OnClick := MenuItem2Click;
      PopupMenu1.Items.Add(Item);
      Item := TMenuItem.Create(PopupMenu1);
      Item.Caption := '菜单三';
      Item.OnClick := MenuItem3Click;
      PopupMenu1.Items.Add(Item);

      Item := TMenuItem.Create(PopupMenu1);
      Item.Caption := '-';        // 增加一个分割条
      PopupMenu1.Items.Add(Item);
      Item := TMenuItem.Create(PopupMenu1);
      Item.Caption := '菜单四';
      Item.OnClick := MenuItem4Click;
      PopupMenu1.Items.Add(Item);

      还可以使用一种更快捷的方法达到同样的目的, 那就是用NewLine和NewItem, 方法如下:

      PopupMenu1 := TPopupMenu.Create(Self);
      with PopUpMenu1.Items do
      begin
        Add(NewItem('菜单一',0,False,True,MenuItem1Click,0,'MenuItem1'));
        Add(NewItem('菜单二',0,False,True,MenuItem2Click,0,'MenuItem2'));
        Add(NewItem('菜单三',0,False,True,MenuItem3Click,0,'MenuItem3'));
        Add(NewLine);             // 增加一个分割条
        Add(NewItem('菜单四',0,False,True,MenuItem4Click,0,'MenuItem4'));
      end;


    二、插入菜单项
      上述方法是在创建完菜单后,紧接着为其添加菜单项目。在已经创建了菜单的情况下,可以在菜单的指定层、指定位置插入菜单。方法如下:

    var M1:TMenuItem;
        n:Integer;
    begin
      M1:=TMenuItem.Create(nil);
      M1.Caption:='菜单名称';
      M1.OnClick:=myMenusClick;     //赋予点击事件
      MainMenu1.Items.Insert(n,M1);  //插入
    end;

    这是在主菜单的根部插入菜单项,如果要在子菜单中插入,其定位方法为:
      MainMenu1.Items[n1].Insert(n2,M1);  //插入子菜单

    如果要为子菜单再插入子项目,则可按下述方法定位:
      MainMenu1.Items[n1].Items[n2].Insert(n3,M1);  //为子菜单插入子项

    添加子菜单的定位方法与此相同,只是缺省了最后一个位置参数,因为添加就是追加到尾部,不需要提供位置信息。n的取置最小为0,最大不能超过当前层级菜单的总数。获取菜单项目数量的方法为:

    var n1,n2,n3:Integer;
    begin
      n1:=MainMenu1.Items.Count;              //根级菜单数
      n2:=MainMenu1.Items[0].Count;           //子级菜单数
      n3:=MainMenu1.Items[0].Items[0].Count;  //孙级菜单数
    end;

    三、删除菜单项
      删除菜单的操作,是插入菜单项的逆向操作,语法相似,定位方位完全一样。只需将插入菜单语句中的Insert改为Delete即可。如需删除主菜单索引号为1(第二个)的子菜单中索引号为2(第三个)的子菜单中的第1(索引号为0)个菜单项,方法如下:

    MainMenu1.Items[1].Items[2].Delete(0);

    四、为菜单项指定快捷方式
      Delphi中有一个ShortCut函数,返回值为TShortCut,可以将它赋值给菜单项的ShortCut属性,从而达到设置快捷键的目的。方法如下:

    var sState:TShiftState;
    begin
      Include(sState, ssCtrl);                  //将Ctrl键加入快捷键组合
      Menu_Left.ShortCut:=ShortCut(37,sState);  //Ctrl+ ←
      Menu_Up.ShortCut:=ShortCut(38,sState);    //Ctrl+ ↑
      Menu_Right.ShortCut:=ShortCut(39,sState); //Ctrl+ →
      Menu_Down.ShortCut:=ShortCut(40,sState);  //Ctrl+ ↓
    end;

    五、为菜单赋予点击事件
      生成菜单的目的,是为了让它响应相应的点击事件,从而快速地执行某些特定的程序功能。无没事件响应的菜单,其存在是毫无意义的。因此,必须为其赋予相应的点击事件。
      菜单的点击事件,可以在程序中一一为其定义,如:

    procedure TForm1.MenuItem1Click(Sender: TObject); //菜单1的点击事件
    begin
      //菜单点击事件的响应程序段
    end;

    procedure TForm1.MenuItem2Click(Sender: TObject); //菜单2的点击事件
    begin
      //菜单点击事件的响应程序段
    end;

    procedure TForm1.MenuItem3Click(Sender: TObject); //菜单3的点击事件
    begin
      //菜单点击事件的响应程序段
    end;

    以此类推。当然也可以共享一个点击事件,但根据触发菜单各自的属性,做出不同的判断,去执行不同的动作。下面的一段代码,可以赋予所有菜单的点击事件,其对菜单的点击事件做出的响应是:显示一句话,并读取当前点击菜单项的名称(Caption属性):

      private
        { Private declarations }
      public
        { Public declarations }
        procedure myMenusClick(Sender: TObject); //通用菜单点击事件

    implementation

    {$R *.dfm}

    procedure TForm1.myMenusClick(Sender: TObject); //通用菜单点击事件
    var menuCap:string;
    begin
      with Sender as TMenuItem do
      begin                                                                       
        menuCap:=TMenuItem(Sender).Caption;
        Application.MessageBox(PChar('你好!'+#13#13'我是菜单“'+menuCap+'”。'
          +#13#13'点击我,有什么吩咐?'),'提醒',MB_Ok+MB_ICONInformation);
      end;     
    end;

    为菜单项赋予点击事件时,有一点需要注意:当菜单项有子菜单时,则该菜单就不应再有点击事件,因为此时该菜单项的点击事件并不是由点击触发的,而是当鼠标进入时就会触发,这样就会导致该菜单的子菜单无法激活的问题,失去了它们存在的意义。对此,可对通用的点击事件作如下修改:
    procedure TForm1.myMenusClick(Sender: TObject); //通用菜单点击事件
    var menuCap:string;
        n:Integer;
    begin
      with Sender as TMenuItem do
      begin                                                                       
        menuCap:=TMenuItem(Sender).Caption;
        n:=TMenuItem(Sender).Count;     //取该菜单的子菜单数
        if n<1 then      //若无子菜单就赋予点击事件,否则忽略点击事件
        Application.MessageBox(PChar('你好!'+#13#13'我是菜单“'+menuCap+'”。'
          +#13#13'点击我,有什么吩咐?'),'提醒',MB_Ok+MB_ICONInformation);
      end;     
    end;

    六、注销菜单
      既然菜单可以动态生成,当然也就可以动态销毁它。方法如下:
      MainMenu1.Items.Clear;  //清除菜单的所有项目
      MainMenu1.Free;         //释放菜单
      用下述方法也可销毁菜单:
      MainMenu1.Destroy;
      但是,一般情况下不应直接调用该方法,应当调用Free方法。

    七、将右键菜单加入到主菜单
      从主菜单激活的都是弹出菜单,在本质上与右键菜单是一样的。因此,右键菜单也可以作为主菜单的一个项目来进行调用。用如下方法可将右键菜单加入到主菜单中去:

    procedure TForm1.btn_toMMClick(Sender: TObject);  //将右键菜单加入到主菜单
    begin
      EnableMenuItem(PopupMenu1.Handle,0,MF_ByPosition);
      AppendMenu(MainMenu1.Handle,MF_Popup,PopupMenu1.Handle,'右键菜单');
      Windows.DrawMenuBar(self.Handle);
    end;
      用下面的方法也可实现将右键菜单加入到主菜单,但在使用中发现退出时会报错,具体原因还未作进一步的研究。
    procedure TForm1.btn_toMMClick(Sender: TObject);  //将右键菜单加入到主菜单
    begin
      MainMenu1.Items.Insert(MainMenu1.Items.Count,PopupMenu1.Items);
      MainMenu1.Items[MainMenu1.Items.Count-1].Caption:='右键菜单';
      DrawMenuBar(Self.Handle);
    end;

    八、菜单的其他属性
      菜单及菜单的项目,不论是动态生成的,还是在设计期部署的,都可以在程序运行期进行改动。对于动态菜单,可以在生成菜单项的同时,对其相关属性、事件一并进行赋值,有两种方法,如下:

    第一种方法,使用NewItem函数:

      PopUpMenu1.Items.Add(NewItem('菜单一',0,False,True,myMenusClick,0,'MenuItem1'));

    使用NewItem函数可以同时为菜单的Caption、ShortCut、HelpContext、Checked、Enabled、Name等六种属性和OnClick

    事件赋值。NewItem函数在Menus.pas单元文件中定义如下:

    function NewItem(const ACaption: string; AShortCut: TShortCut;
      AChecked, AEnabled: Boolean; AOnClick: TNotifyEvent; hCtx: THelpContext;
      const AName: string): TMenuItem;
    begin
      Result := TMenuItem.Create(nil);
      with Result do
      begin
        Caption := ACaption;
        ShortCut := AShortCut;
        OnClick := AOnClick;
        HelpContext := hCtx;
        Checked := AChecked;
        Enabled := AEnabled;
        Name := AName;
      end;
    end;

    第二种方法,在生成菜单项后,分别为其相应的属性或事件赋值。这种方法比较灵活,可以只对其中某几个属性或事件赋值,也可以为其全部属性和事件赋值。方法如下:

    var M1:TMenuItem;
        n:Integer;
        myShortCut:TShortCut;
    begin
      M1:=TMenuItem.Create(nil);
      M1.Caption:='菜单名称';      //赋予菜单名称
      M1.AutoHotkeys:=maManual;   //关闭自动热键(人工)
      M1.OnClick:=myMenusClick;    //赋予点事件
      M1.ShortCut:=myShortCut;   //赋予快捷键 
      //为其他属性赋值
      //为其他事件赋值
      MainMenu1.Items.Insert(n,M1);  //插入
    end;

  • 相关阅读:
    【数据操作】存储过程编写经验和优化措施
    【项目管理】产品经理的核心能力模型(译)
    [转] SAP DEVELOPMENT TECHNOLOGY LIST
    【架构设计】五个基本工作流模式(转)
    【工具推荐】Office Open XML
    【经验分享】企业可选的当前主流OA产品
    【项目管理】项目启动阶段 制定项目章程
    【转贴文章】 Dos命令收集
    【架构设计】Web应用程序安全性简介
    [转]what is SAP NetWeaver
  • 原文地址:https://www.cnblogs.com/jijm123/p/7456328.html
Copyright © 2011-2022 走看看