档案 编辑 选项 --> 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
上一篇: 在VB中设计倒计时程序
下一篇: Visual Basic的工程限制
文章整理:西部数码--专业提供域名注册、虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!




