本文題目所說的系統菜單不是指應用程序系統的菜單,而是指當用戶用鼠標左鍵單擊應用程序窗體左上角的圖標時彈出的菜單。同樣,當用戶用鼠標右鍵單擊應用程序窗體的標題欄,或系統任務欄中的應用程序標題時,彈出的也是這個菜單。系統菜單與應用程序菜單不一樣,系統菜單不受應用程序控制,它是由Windows系統直接控制的。因此,在系統菜單上添加自定義菜單項,就顯得比較困難。以下便是本人利用VB實現在系統菜單上添加自定義菜單項的方法。
----首先需要知道一點是系統菜單的工作過程。當我們單擊系統菜單中某一項時,應用程序窗口會收到一條WM_SYSCOMMAND消息,該消息包含了系統菜單中所單擊那一項的標識符ID。此時,應用程序窗口的默認窗口函數會根據WM_SYSCOMMAND消息以及菜單標識符ID執行相應的操作,完成菜單命令。如果我們能攔截到達窗口的WM_SYSCOMMAND消息,並且識別出菜單的標識符ID,我們就能夠在系統菜單上添加自己的菜單項,並且執行指定的動作。下面的例子就是在系統菜單上添加一條分隔符和"關於…"菜單項。
----啟動VisualBasic,新建標准EXE工程,在工程中添加一標准模塊,名稱可以是默認的。在標准模塊的聲明部分加入下列代碼:
'菜單API函數聲明
PublicDeclareFunctionGetSystemMenuLib"user32"(ByValhwndAsLong,ByValbRevertAsLong)AsLong
PublicDeclareFunctionAppendMenuLib"user32"Alias"AppendMenuA"(ByValhMenuAsLong,ByValwFlagsAsLong,ByValwIDNewItemAsLong,ByVallpNewItemAsAny)AsLong'菜單API函數常數聲明
PublicConstMF_BYCOMMAND="H0"
PublicConstMF_SEPARATOR="H800"
PublicConstMF_STRING="H0"'有關窗口函數的API函數聲明
PublicDeclareFunctionSetWindowLongLib"user32"Alias"SetWindowLongA"(ByValhwndAsLong,ByValnIndexAsLong,ByValdwNewLongAsLong)AsLong
PublicDeclareFunctionCallWindowProcLib"user32"Alias"CallWindowProcA"(ByVallpPrevWndFuncAsLong,ByValhwndAsLong,ByValMsgAsLong,ByValwParamAsLong,ByVallParamAsLong)AsLong
PublicDeclareFunctionDefWindowProcLib"user32"Alias"DefWindowProcA"(ByValhwndAsLong,ByValwMsgAsLong,ByValwParamAsLong,ByVallParamAsLong)AsLong'消息
PublicConstGWL_WNDPROC=(-4)
PublicConstWM_NCLBUTTONDOWN="HA1"
PublicConstWM_NCRBUTTONDOWN="HA4"
PublicConstWM_USER="H400"
PublicConstWM_SYSCOMMAND="H112"
PublicConstHTSYSMENU=3
PublicConstHTCAPTION=2'自定義菜單項的標識號偏移量
PublicConstIDM_SEPARATOR=1
PublicConstIDM_MYABOUT=2'其他變量
DimsHwndAsLong
DimOldProcAsLong
接著可向標准模塊添加下面兩個過程:PublicSubAddMenu(frmAsForm)'置換窗口函數過程
sHwnd=frm.hwnd
OldProc=SetWindowLong(frm.hwnd,GWL_WNDPROC,AddressOfAddCallBack)
EndSub
PublicSubRelease()'釋放自定義窗口函數過程
SetWindowLongsHwnd,GWL_WNDPROC,OldProc
EndSub
最後向標准模塊中添加一自定義窗口函數過程:
PublicFunctionAddCallBack(ByValhwndAsLong,ByValwMsgAsLong,ByValwParamAsLong,ByVallParamAsLong)AsLongSelectCasewMsgCaseWM_SYSCOMMAND
'系統消息
SelectCasewParam'測試
CaseWM_USER IDM_MYABOUT
'"關於..."菜單項
'此處可加入用戶需要自己處理"關於…"菜單項的代碼
MsgBox"單擊了添加的菜單條目",vbOKOnly
CaseElse'其它菜單項交換系統處理
AddCallBack=DefWindowProc(hwnd,wMsg,wParam,lParam)
EndSelect
ExitFunction
CaseElse
AddCallBack=CallWindowProc(OldProc,hwnd,wMsg,wParam,lParam)End
SelectEnd
Function關閉標准模塊的代碼窗口,打開窗體的代碼窗口,在Form_Load()過程中加入下列代碼:
'加載自定義窗口過程AddMenuMe'獲得系統菜單的句柄Dim
hMenuAsLonghMenu=GetSystemMenu(Me.hwnd,0)'在系統菜單中添加自定義2條菜單項
AppendMenuhMenu,MF_SEPARATOROrMF_BYCOMMAND,IDM_SEPARATOR,
vbNullString'分隔符AppendMenuhMenu,MF_BYCOMMANDOrMF_STRING,
WM_USER IDM_MYABOUT,"關於..."'"關於…"菜單項
在Form_Unload過程中加入下列代碼:Release'釋放自定義窗口過程
----到此,代碼的輸入工作完成,接下來的是進行測試。單擊啟動按鈕或按F5,啟動工程,用鼠標單擊窗體左上角的圖標彈出系統菜單,看看是否如願。千萬要注意的一點是,在結束工程時,一定要用窗體右上角的關閉按鈕或者系統菜單中的關閉菜單項,否則的話,會造成VisualBasic系統崩潰,出現非法操作的錯誤,所以在測試工程前,最好對工程進行保存。
----以上程序在Windows95,VisualBasic6.0環境下調試通過。->