VB:如何实现在代码中弹出toolbar的ButtonMenu?

首先,需要指出的是toolbar的ButtonMenu不是标准的menu,所以用TrackPopupMenu之类的api函数无法达到我们的目的,事实上当用户点击dropdown button时,toolbar会发送TBN_DROPDOWN这条通知消息,所以我们只要用代码模拟发送这条通知消息即可。代码如下:

Option Explicit

Private Type TBBUTTON

iBitmap As Long

idCommand As Long

fsState As Byte

fsStyle As Byte

bReserved1 As Byte

bReserved2 As Byte

dwData As Long

iString As Long

End Type

Private Type NMHDR

hwndFrom As Long

idfrom As Long

code As Long

End Type

Private Type NMTOOLBAR

hdr As NMHDR

iItem As Long

tbBtn As TBBUTTON

cchText As Long

lpszString As Long

End Type

Private Const TBN_FIRST = -700&

Private Const TBN_DROPDOWN = (TBN_FIRST - 10)

Private Const WM_USER = &H400

Private Const TB_GETBUTTON As Long = (WM_USER + 23)

Private Const WM_NOTIFY As Long = &H4E&

Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long

Private Sub Toolbar1_ButtonClick(ByVal Button As MSComctlLib.Button)

If Button.Index = 4 Then '假如toolbar上的第4个按钮有buttonmenu,同时其样式为5

showbuttonmenu Toolbar1, Button.Index - 1

End If

End Sub

Private Sub showbuttonmenu(Toolbar1 As MSComctlLib.Toolbar, ByVal Buttonindex As Long) 'buttonindex从0开始

Dim tButton As TBBUTTON

Dim tNotify As NMTOOLBAR

Dim lResult As Long

Dim mhwnd As Long

Dim lCommandId As Long

mhwnd = FindWindowEx(Toolbar1.hwnd, 0, "msvb_lib_toolbar", vbNullString)

lResult = SendMessage(mhwnd, TB_GETBUTTON, Buttonindex, tButton)

lCommandId = tButton.idCommand

With tNotify

.hdr.code = TBN_DROPDOWN

.hdr.hwndFrom = mhwnd

.iItem = lCommandId

End With

lResult = SendMessage(Toolbar1.hwnd, WM_NOTIFY, 0, tNotify)

End Sub