?? 60.txt
字號:
得知目前Mouse所指的Menu Item是哪一個
請先查閱有BitMap的Menu取得Menu的相關知識,再查
如何攔截ComboBox MouseMove的SubClass之技巧
一些商業軟件中,當滑鼠指向某個Menu Item時,在表單的底部STATUSBAR中會顯示有該Item
功能的簡要說明。而VB5中有關Menu的捕捉事件只有一個 CLICK,那該如何做呢。其實當
選擇了Menu後,Mouse在Menu SubMenu MenuItem上移來移去時,會產生WM_MENUSELECT的
Message給Menu所在的表單,而其wParam的Low Word有兩個意義,如果Mouse指到的Item
之下還有子Menu,該LowWord of wParam指的是該Item是第幾個SubMenu,而lParam便是
Menu的Handle;相反的,如果Mouse所指的Item底下沒有PopupMenu了,那 LowWord of
wParam指的是MenuID,而lParam是hSubMenu。
檔案 編輯 選項 --> hMenu (功能表, Menu)
+-------+
|復制 |---------> hSubMenu (子功能表, SubMenu)
|貼上 |
|減下 -------------> MenuID (功能表項目,MenuItem)
| |
+-------+
所以了,這就得使用SubClass的技巧,取得WM_MENUSELECT的Message,進而得知到底是
選到了哪一個MenuItem。當然了,我們可以使用GetMenu GetSubMenu GetMenuItemID
等API來得知功能表上每一個項目的hMenu hSubMenu MenuID,如此一來,和WM_MENUSELECT
訊息所取得的lParam wParam做做比較,就可得知到底選上了哪一個,而本例則是使用
GetMenuString取得MenuItem的title,如果您的MenuItems沒有相同的title,也不失一
得知方式。
'以下在form,請自行加Menu於Form上
Private Sub Form_Load()
Dim ret As Long
hMenu = GetMenu(Me.hwnd)
'記錄原本的Window Procedure的位址
preWinProc = GetWindowLong(Me.hwnd, GWL_WNDPROC)
'設定Combo1的window Procedure到wndproc
ret = SetWindowLong(Me.hwnd, GWL_WNDPROC, AddressOf wndproc)
End Sub
Private Sub Form_Unload(Cancel As Integer)
Dim ret As Long
'取消Message的截取,而使之又只送往原來的Window Procedure
ret = SetWindowLong(Me.hwnd, GWL_WNDPROC, preWinProc)
End Sub
'以下在.Bas
'以下程式在module1.bas
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _
(ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _
(ByVal hwnd As Long, ByVal nIndex As Long) As Long
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
Declare Function GetMenuString Lib "user32" Alias "GetMenuStringA" (ByVal hMenu As Long, ByVal wIDItem As Long, ByVal lpString As String, ByVal nMaxCount As Long, ByVal wFlag As Long) As Long
Declare Function GetMenu Lib "user32" (ByVal hwnd As Long) As Long
Declare Function GetSubMenu Lib "user32" (ByVal hMenu As Long, ByVal nPos As Long) As Long
Public Const GWL_WNDPROC = (-4)
Public Const WM_MENUSELECT = &H11F
Public Const MF_BYCOMMAND = &H0&
Public Const MF_BYPOSITION = &H400&
Public hMenu As Long
Public preWinProc As Long
Private Type tLong
ll As Long
End Type
Private Type TwoWord
LowWord As Integer
HiWord As Integer
End Type
Public Function wndproc(ByVal hwnd As Long, ByVal Msg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long
Dim MenuItemStr As String, SubMenuStr As String
Dim hSubmenu As Long, MenuId As Long, i As Long
Dim tmpl As tLong, tmpt As TwoWord
'以下程式會截取WM_MENUSELECT處理完後,再將之送往原來的Window Procedure
If Msg = WM_MENUSELECT Then
SubMenuStr = String(255, 0)
MenuItemStr = String(255, 0)
tmpl.ll = wParam
LSet tmpt = tmpl
MenuId = tmpt.LowWord
hSubmenu = GetSubMenu(lParam, MenuId)
If hSubmenu = 0 Then '表示該item之下沒有popupMenu了
Call GetMenuString(lParam, MenuId, MenuItemStr, 256, MF_BYCOMMAND)
MenuItemStr = Left(MenuItemStr, InStr(1, MenuItemStr, Chr(0)) - 1)
Debug.Print "正在 MenuItem " + MenuItemStr
Else
Call GetMenuString(hMenu, hSubmenu, SubMenuStr, 256, MF_BYCOMMAND)
SubMenuStr = Left(SubMenuStr, InStr(1, SubMenuStr, Chr(0)) - 1)
Debug.Print "正在 PopUpMenu " + SubMenuStr
End If
End If
'將之送往原來的Window Procedure
wndproc = CallWindowProc(preWinProc, hwnd, Msg, wParam, lParam)
End Function
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -