top
Loading...
在系統菜單上添加自定義菜單項
”疚奶餑克檔南低巢說ゲ皇侵贛τ貿絳螄低車牟說ィ侵傅庇沒в檬蟊曜蠹セ饔τ貿絳虼疤遄笊轄塹耐急曄鋇齙牟說ァM庇沒в檬蟊曖壹セ饔τ貿絳虼疤宓謀晏飫福螄低橙撾窶鋼械撓τ貿絳蟣晏饈保齙囊彩欽飧霾說ァO低巢說ビ胗τ貿絳蠆說ゲ灰謊低巢說ゲ皇苡τ貿絳蚩刂疲怯蒞indows系統直接控制的。因此,在系統菜單上添加自定義菜單項,就顯得比較困難。以下便是本人利用VB實現在系統菜單上添加自定義菜單項的方法。
首先需要知道一點是系統菜單的工作過程。當我們單擊系統菜單中某一項時,應用程序窗口會收到一條WM_SYSCOMMAND消息,該消息包含了系統菜單中所單擊那一項的標識符ID。此時,應用程序窗口的默認窗口函數會根據WM_SYSCOMMAND消息以及菜單標識符ID執行相應的操作,完成菜單命令。如果我們能攔截到達窗口的WM_SYSCOMMAND消息,并且識別出菜單的標識符ID,我們就能夠在系統菜單上添加自己的菜單項,并且執行指定的動作。下面的例子就是在系統菜單上添加一條分隔符和"關于…"菜單項。

啟動Visual Basic,新建標準EXE工程,在工程中添加一標準模塊,名稱可以是默認的。在標準模塊的聲明部分加入下列代碼:

菜單API函數聲明
Public Declare Function GetSystemMenu Lib "user32" (ByVal hwnd As Long, ByVal bRevert As Long) As Long
Public Declare Function AppendMenu Lib "user32" Alias "AppendMenuA" (ByVal hMenu As Long, ByVal wFlags As Long, ByVal wIDNewItem As Long, ByVal lpNewItem As Any) As Long 菜單API函數常數聲明
Public Const MF_BYCOMMAND = "H0"
Public Const MF_SEPARATOR ="H800"
Public Const MF_STRING = "H0" 有關窗口函數的API函數聲明
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long,ByVal dwNewLong As Long) As Long
Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Declare Function DefWindowProc Lib "user32" Alias "DefWindowProcA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long 消息
Public Const GWL DPROC = (-4)
Public Const WM_NCLBUTTONDOWN = "HA1"
Public Const WM_NCRBUTTONDOWN = "HA4"
Public Const WM_USER = "H400"
Public Const WM_SYSCOMMAND = "H112"
Public Const HTSYSMENU = 3
Public Const HTCAPTION = 2 自定義菜單項的標識號偏移量
Public Const IDM_SEPARATOR = 1
Public Const IDM_MYABOUT = 2 其他變量
Dim sHwnd As Long
Dim OldProc As Long
接著可向標準模塊添加下面兩個過程: Public Sub AddMenu(frm As Form) 置換窗口函數過程
sHwnd = frm.hwnd
OldProc = SetWindowLong(frm.hwnd, GWL_WNDPROC, AddressOf AddCallBack)
End Sub
Public Sub Release() 釋放自定義窗口函數過程
SetWindowLong sHwnd,GWL_WNDPROC, OldProc
End Sub

最后向標準模塊中添加一自定義窗口函數過程:
Public Function AddCallBack(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Select Case wMsg Case WM_SYSCOMMAND
系統消息
Select Case wParam 測試
Case WM_USER + IDM_MYABOUT
"關于..."菜單項
此處可加入用戶需要自己處理"關于…" 菜單項的代碼
MsgBox "單擊了添加的菜單條目",vbOKOnly

Case Else 其它菜單項交換系統處理
AddCallBack =DefWindowProc(hwnd, wMsg, wParam, lParam)
End Select
Exit Function
Case Else
AddCallBack = CallWindowProc(OldProc, hwnd, wMsg, wParam, lParam) End
Select End
Function 關閉標準模塊的代碼窗口,打開窗體的代碼窗口, 在Form_Load()過程中加入下列代碼:
加載自定義窗口過程 AddMenu Me 獲得系統菜單的句柄 Dim
hMenu As Long hMenu = GetSystemMenu(Me.hwnd, 0) 在系統菜單中添加自定義2條菜單項
AppendMenu hMenu, MF_SEPARATOR Or MF_BYCOMMAND, IDM_SEPARATOR,
vbNullString 分隔符 AppendMenu hMenu, MF_BYCOMMAND Or MF_STRING,
WM_USER + IDM_MYABOUT, "關于..." "關于…"菜單項
在Form_Unload過程中加入下列代碼: Release 釋放自定義窗口過程

到此,代碼的輸入工作完成,接下來的是進行測試。單擊啟動按鈕或按F5,啟動工程,用鼠標單擊窗體左上角的圖標彈出系統菜單,看看是否如愿。千萬要注意的一點是,在結束工程時,一定要用窗體右上角的關閉按鈕或者系統菜單中的關閉菜單項,否則的話,會造成Visual Basic系統崩潰,出現非法操作的錯誤,所以在測試工程前,最好對工程進行保存。
以上程序在Windows95,Visual Basic6.0環境下調試通過。

作者:http://www.zhujiangroad.com
來源:http://www.zhujiangroad.com
北斗有巢氏 有巢氏北斗