一、創(chuàng)建菜單并添加項(xiàng)目
在設(shè)計(jì)程序時(shí),有時(shí)需要?jiǎng)討B(tài)創(chuàng)建菜單, 通常使用以下的語句:
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 := '-'; // 增加一個(gè)分割條
PopupMenu1.Items.Add(Item);
Item := TMenuItem.Create(PopupMenu1);
Item.Caption := '菜單四';
Item.OnClick := MenuItem4Click;
PopupMenu1.Items.Add(Item);
還可以使用一種更快捷的方法達(dá)到同樣的目的, 那就是用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); // 增加一個(gè)分割條
Add(NewItem('菜單四',0,False,True,MenuItem4Click,0,'MenuItem4'));
end;
二、插入菜單項(xiàng)
上述方法是在創(chuàng)建完菜單后,緊接著為其添加菜單項(xiàng)目。在已經(jīng)創(chuàng)建了菜單的情況下,可以在菜單的指定層、指定位置插入菜單。方法如下:
var M1:TMenuItem;
n:Integer;
begin
M1:=TMenuItem.Create(nil);
M1.Caption:='菜單名稱';
M1.OnClick:=myMenusClick; //賦予點(diǎn)擊事件
MainMenu1.Items.Insert(n,M1); //插入
end;
這是在主菜單的根部插入菜單項(xiàng),如果要在子菜單中插入,其定位方法為:
MainMenu1.Items[n1].Insert(n2,M1); //插入子菜單
如果要為子菜單再插入子項(xiàng)目,則可按下述方法定位:
MainMenu1.Items[n1].Items[n2].Insert(n3,M1); //為子菜單插入子項(xiàng)
添加子菜單的定位方法與此相同,只是缺省了最后一個(gè)位置參數(shù),因?yàn)樘砑泳褪亲芳拥轿膊浚恍枰峁┪恢眯畔?。n的取置最小為0,最大不能超過當(dāng)前層級(jí)菜單的總數(shù)。獲取菜單項(xiàng)目數(shù)量的方法為:
var n1,n2,n3:Integer;
begin
n1:=MainMenu1.Items.Count; //根級(jí)菜單數(shù)
n2:=MainMenu1.Items[0].Count; //子級(jí)菜單數(shù)
n3:=MainMenu1.Items[0].Items[0].Count; //孫級(jí)菜單數(shù)
end;
三、刪除菜單項(xiàng)
刪除菜單的操作,是插入菜單項(xiàng)的逆向操作,語法相似,定位方位完全一樣。只需將插入菜單語句中的Insert改為Delete即可。如需刪除主菜單索引號(hào)為1(第二個(gè))的子菜單中索引號(hào)為2(第三個(gè))的子菜單中的第1(索引號(hào)為0)個(gè)菜單項(xiàng),方法如下:
MainMenu1.Items[1].Items[2].Delete(0);
四、為菜單項(xiàng)指定快捷方式
Delphi中有一個(gè)ShortCut函數(shù),返回值為TShortCut,可以將它賦值給菜單項(xiàng)的ShortCut屬性,從而達(dá)到設(shè)置快捷鍵的目的。方法如下:
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;
五、為菜單賦予點(diǎn)擊事件
生成菜單的目的,是為了讓它響應(yīng)相應(yīng)的點(diǎn)擊事件,從而快速地執(zhí)行某些特定的程序功能。無沒事件響應(yīng)的菜單,其存在是毫無意義的。因此,必須為其賦予相應(yīng)的點(diǎn)擊事件。
菜單的點(diǎn)擊事件,可以在程序中一一為其定義,如:
procedure TForm1.MenuItem1Click(Sender: TObject); //菜單1的點(diǎn)擊事件
begin
//菜單點(diǎn)擊事件的響應(yīng)程序段
end;
procedure TForm1.MenuItem2Click(Sender: TObject); //菜單2的點(diǎn)擊事件
begin
//菜單點(diǎn)擊事件的響應(yīng)程序段
end;
procedure TForm1.MenuItem3Click(Sender: TObject); //菜單3的點(diǎn)擊事件
begin
//菜單點(diǎn)擊事件的響應(yīng)程序段
end;
以此類推。當(dāng)然也可以共享一個(gè)點(diǎn)擊事件,但根據(jù)觸發(fā)菜單各自的屬性,做出不同的判斷,去執(zhí)行不同的動(dòng)作。下面的一段代碼,可以賦予所有菜單的點(diǎn)擊事件,其對(duì)菜單的點(diǎn)擊事件做出的響應(yīng)是:顯示一句話,并讀取當(dāng)前點(diǎn)擊菜單項(xiàng)的名稱(Caption屬性):
private
{ Private declarations }
public
{ Public declarations }
procedure myMenusClick(Sender: TObject); //通用菜單點(diǎn)擊事件
implementation
{$R *.dfm}
procedure TForm1.myMenusClick(Sender: TObject); //通用菜單點(diǎn)擊事件
var menuCap:string;
begin
with Sender as TMenuItem do
begin
menuCap:=TMenuItem(Sender).Caption;
Application.MessageBox(PChar('你好!'+#13#13'我是菜單“'+menuCap+'”。'
+#13#13'點(diǎn)擊我,有什么吩咐?'),'提醒',MB_Ok+MB_ICONInformation);
end;
end;
為菜單項(xiàng)賦予點(diǎn)擊事件時(shí),有一點(diǎn)需要注意:當(dāng)菜單項(xiàng)有子菜單時(shí),則該菜單就不應(yīng)再有點(diǎn)擊事件,因?yàn)榇藭r(shí)該菜單項(xiàng)的點(diǎn)擊事件并不是由點(diǎn)擊觸發(fā)的,而是當(dāng)鼠標(biāo)進(jìn)入時(shí)就會(huì)觸發(fā),這樣就會(huì)導(dǎo)致該菜單的子菜單無法激活的問題,失去了它們存在的意義。對(duì)此,可對(duì)通用的點(diǎn)擊事件作如下修改:
procedure TForm1.myMenusClick(Sender: TObject); //通用菜單點(diǎn)擊事件
var menuCap:string;
n:Integer;
begin
with Sender as TMenuItem do
begin
menuCap:=TMenuItem(Sender).Caption;
n:=TMenuItem(Sender).Count; //取該菜單的子菜單數(shù)
if n<1 then //若無子菜單就賦予點(diǎn)擊事件,否則忽略點(diǎn)擊事件
Application.MessageBox(PChar('你好!'+#13#13'我是菜單“'+menuCap+'”。'
+#13#13'點(diǎn)擊我,有什么吩咐?'),'提醒',MB_Ok+MB_ICONInformation);
end;
end;
六、注銷菜單
既然菜單可以動(dòng)態(tài)生成,當(dāng)然也就可以動(dòng)態(tài)銷毀它。方法如下:
MainMenu1.Items.Clear; //清除菜單的所有項(xiàng)目
MainMenu1.Free; //釋放菜單
用下述方法也可銷毀菜單:
MainMenu1.Destroy;
但是,一般情況下不應(yīng)直接調(diào)用該方法,應(yīng)當(dāng)調(diào)用Free方法。
七、將右鍵菜單加入到主菜單
從主菜單激活的都是彈出菜單,在本質(zhì)上與右鍵菜單是一樣的。因此,右鍵菜單也可以作為主菜單的一個(gè)項(xiàng)目來進(jìn)行調(diào)用。用如下方法可將右鍵菜單加入到主菜單中去:
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;
用下面的方法也可實(shí)現(xiàn)將右鍵菜單加入到主菜單,但在使用中發(fā)現(xiàn)退出時(shí)會(huì)報(bào)錯(cuò),具體原因還未作進(jìn)一步的研究。
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;
八、菜單的其他屬性
菜單及菜單的項(xiàng)目,不論是動(dòng)態(tài)生成的,還是在設(shè)計(jì)期部署的,都可以在程序運(yùn)行期進(jìn)行改動(dòng)。對(duì)于動(dòng)態(tài)菜單,可以在生成菜單項(xiàng)的同時(shí),對(duì)其相關(guān)屬性、事件一并進(jìn)行賦值,有兩種方法,如下:
第一種方法,使用NewItem函數(shù):
PopUpMenu1.Items.Add(NewItem('菜單一',0,False,True,myMenusClick,0,'MenuItem1'));
使用NewItem函數(shù)可以同時(shí)為菜單的Caption、ShortCut、HelpContext、Checked、Enabled、Name等六種屬性和OnClick
事件賦值。NewItem函數(shù)在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;
第二種方法,在生成菜單項(xiàng)后,分別為其相應(yīng)的屬性或事件賦值。這種方法比較靈活,可以只對(duì)其中某幾個(gè)屬性或事件賦值,也可以為其全部屬性和事件賦值。方法如下:
var M1:TMenuItem;
n:Integer;
myShortCut:TShortCut;
begin
M1:=TMenuItem.Create(nil);
M1.Caption:='菜單名稱'; //賦予菜單名稱
M1.AutoHotkeys:=maManual; //關(guān)閉自動(dòng)熱鍵(人工)
M1.OnClick:=myMenusClick; //賦予點(diǎn)事件
M1.ShortCut:=myShortCut; //賦予快捷鍵
//為其他屬性賦值
//為其他事件賦值
MainMenu1.Items.Insert(n,M1); //插入
end;
聯(lián)系客服