Solved

Windows Common Controls:  Toolbar Button with Drop Menu

Posted on 2004-08-26
12
648 Views
Last Modified: 2013-12-25
Is it possible to have the drop menu show when you click on a button that has tbrDropDown style?

Bob
0
Comment
Question by:Bob Learned
  • 6
  • 5
12 Comments
 
LVL 49

Expert Comment

by:Ryan Chong
ID: 11909142
What i usually done is create a list of menu items via Menu Editor, then set the root menu item's Visible Property to False. So, later in the toolbar ButtonClick Event, show it when the button is clicked.

Example:

Private Sub Toolbar1_ButtonClick(ByVal Button As MSComctlLib.Button)
    If Button.Index = 1 Then
        PopupMenu menu1
    Else
   
    End If
End Sub
0
 
LVL 49

Accepted Solution

by:
Ryan Chong earned 500 total points
ID: 11909189
if the button's style is tbrDropDown, try use ButtonDropDown event instead, like:

Private Sub Toolbar1_ButtonDropDown(ByVal Button As MSComctlLib.Button)
    If Button.Index = 1 Then
        PopupMenu menu1, , Button.Left, Button.Top + Button.Height
    Else
   
    End If
End Sub
0
 
LVL 1

Expert Comment

by:Arnee_Senthil
ID: 11911363
Yes we can easily create the dropdown tool bar item in runtime...

I have given some sample code.

Private Sub Form_Load()
'===========================================
' This section adds toolbar button and 3 drop down buttons
'===========================================
With Toolbar
        .Buttons.Add 1, "MainToolBar"
        .Buttons.Item(1).ToolTipText = "Others"
        .Buttons.Item(1).Caption = "Main Tool Bar"
        .Buttons.Item(1).Style = tbrDropdown

        .Buttons.Item(1).ButtonMenus.Add 1, "Drop Down 1", "Drop Down 1"
        .Buttons.Item(1).ButtonMenus.Add 2, "Drop Down 2", "Drop Down 2"
        .Buttons.Item(1).ButtonMenus.Add 3, "Drop Down 3", "Drop Down 3"
End With
End Sub

Private Sub Toolbar_ButtonMenuClick(ByVal ButtonMenu As MSComctlLib.ButtonMenu)
'===================================================
' This section diff. the button click in tool bar.
'===================================================
    Select Case ButtonMenu
        Case "Drop Down 1"
            MsgBox "Drop Down 1"
        Case "Drop Down 2"
            MsgBox "Drop Down 2"
        Case "Drop Down 3"
            MsgBox "Drop Down 3"
    End Select
       
End Sub


Hope I gave enough idea abt dropdown tool bar btn,

Arne
0
 
LVL 49

Expert Comment

by:Ryan Chong
ID: 11911571
Arnee_Senthil, nice one, i forget that method totally, thks for remain me that ;-) cheers
0
 
LVL 96

Author Comment

by:Bob Learned
ID: 11911931
Okay, maybe I didn't make myself very clear.  I know how to create ButtonMenu items.  I would like to be able to show the ButtonMenus when clicking on a button that already has them defined.  I couldn't find a method to show the drop down menu from the button.  PopupMenu can only show MenuItems, as far as I know.

It's just one of those silly user requirements, where they can't figure out how to click on the drop down arrow to show the button menus.  I was thinking that it would take some magic to get this done, and I was wondering if someone had already solved this problem, since I am trying to meet a deadline.

Thanks for all your efforts.

Bob
0
 
LVL 49

Expert Comment

by:Ryan Chong
ID: 11913891
Hi TheLearnedOne,

I think the easiest way may is to use the popupmenu method to popup a menu.. yet, i try to stimulate the click, by calculate the button's position, follow by stimulate a mouse click event, just like what i'm trying below:

Example:

Private Declare Sub mouse_event Lib "user32" (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As Long)
Const MOUSEEVENTF_LEFTDOWN = &H2
Const MOUSEEVENTF_LEFTUP = &H4
Const MOUSEEVENTF_MIDDLEDOWN = &H20
Const MOUSEEVENTF_MIDDLEUP = &H40
Const MOUSEEVENTF_MOVE = &H1
Const MOUSEEVENTF_ABSOLUTE = &H8000
Const MOUSEEVENTF_RIGHTDOWN = &H8
Const MOUSEEVENTF_RIGHTUP = &H10

Private Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type
Private Type POINTAPI
    X As Long
    Y As Long
End Type

Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
Private Declare Function SetCursorPos Lib "user32" (ByVal X As Long, ByVal Y As Long) As Long
Private Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long

Private Sub StimulateButtonMenuDropDown(ByVal btn As MSComctlLib.Button, Optional tryClickDropDown As Boolean = False)
    Dim curPos As POINTAPI
    GetCursorPos curPos
    If tryClickDropDown Then
        SetCursorPos (Me.Left / Screen.TwipsPerPixelX) + (btn.Left + btn.Width) - 5, (Me.Top / Screen.TwipsPerPixelY) + (btn.Top + btn.Height)
    Else
        SetCursorPos (Me.Left / Screen.TwipsPerPixelX) + (btn.Left + (btn.Width / 2)), (Me.Top / Screen.TwipsPerPixelY) + (btn.Top + btn.Height)
    End If
    mouse_event MOUSEEVENTF_LEFTDOWN Or MOUSEEVENTF_LEFTUP, 0&, 0&, cButt, dwEI
    SetCursorPos curPos.X, curPos.Y
End Sub

Private Sub Command1_Click(Index As Integer)
    Select Case Index
    Case 0
        StimulateButtonMenuDropDown Toolbar1.Buttons(1)
    Case 1
        StimulateButtonMenuDropDown Toolbar1.Buttons(2)
    Case 2
        StimulateButtonMenuDropDown Toolbar1.Buttons(3)
    Case 3
        StimulateButtonMenuDropDown Toolbar1.Buttons(2), True
    End Select
End Sub

Private Sub Form_Load()
    Me.ScaleMode = vbPixels
    With Toolbar1
        .Buttons.Add 1, "test 1"
        .Buttons(1).Caption = "button 1"
       
        .Buttons.Add 2, "MainToolBar"
        .Buttons(2).Caption = "button 2"
        .Buttons.Item(2).ToolTipText = "Others"
        .Buttons.Item(2).Caption = "Main Tool Bar"
        .Buttons.Item(2).Style = tbrDropdown
       
        .Buttons.Item(2).ButtonMenus.Add 1, "Drop Down 1", "Drop Down 1"
        .Buttons.Item(2).ButtonMenus.Add 2, "Drop Down 2", "Drop Down 2"
        .Buttons.Item(2).ButtonMenus.Add 3, "Drop Down 3", "Drop Down 3"
       
        .Buttons.Add 3, "test 3"
        .Buttons(3).Caption = "button 3"
    End With
    Command1(0).Caption = "Click button 1"
    Command1(1).Caption = "Click button 2"
    Command1(2).Caption = "Click button 3"
    Command1(3).Caption = "Click button 2's drop down"
End Sub

Private Sub Toolbar1_ButtonClick(ByVal Button As MSComctlLib.Button)
    MsgBox Button.Caption & " is clicked"
End Sub

Private Sub Toolbar1_ButtonMenuClick(ByVal ButtonMenu As MSComctlLib.ButtonMenu)
    Select Case ButtonMenu
    Case "Drop Down 1"
        MsgBox "Drop Down 1"
    Case "Drop Down 2"
        MsgBox "Drop Down 2"
    Case "Drop Down 3"
        MsgBox "Drop Down 3"
    End Select
End Sub

'Hope this will help

regards
0
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
LVL 96

Author Comment

by:Bob Learned
ID: 11913903
Now, this is the kind of magic that I am talking about :)

Thank you very much.  I will try this out, and let you know.

Bob
0
 
LVL 96

Author Comment

by:Bob Learned
ID: 11916033
ryancys:

In StimulateButtonMenuDropDown, what are the last two parameters for this line:

mouse_event MOUSEEVENTF_LEFTDOWN Or MOUSEEVENTF_LEFTUP, 0&, 0&, cButt, dwEI

cButt and dwEI.

Bob
0
 
LVL 96

Author Comment

by:Bob Learned
ID: 11916167
I can't quite get it to work.

Bob
0
 
LVL 96

Author Comment

by:Bob Learned
ID: 11916190
This is what I have so far:

Public Sub SendMouseClickToButton(ByRef frmOwner As Form, ByRef btnCurrent As Button)

Dim lRtn As Long
Dim lButtonHeight As Long
Dim lButtonLeft As Long
Dim lButtonTop As Long
Dim lButtonWidth As Long
Dim udtCursorPos As POINTAPI

   lButtonLeft = frmOwner.ScaleX(btnCurrent.Left, vbTwips, vbPixels)
   lButtonTop = frmOwner.ScaleY(btnCurrent.Top, vbTwips, vbPixels)
   lButtonWidth = frmOwner.ScaleX(btnCurrent.Width, vbTwips, vbPixels)
   lButtonHeight = frmOwner.ScaleY(btnCurrent.Height, vbTwips, vbPixels)
   
   lRtn = GetCursorPos(udtCursorPos)
   
   lRtn = SetCursorPos(lButtonLeft + lButtonWidth - 10, (lButtonTop + lButtonHeight) \ 2)
   
   Call mouse_event(MOUSEEVENTF_LEFTDOWN Or MOUSEEVENTF_LEFTUP, 0&, 0&, 0&, 0&)
   
   lRtn = SetCursorPos(udtCursorPos.x, udtCursorPos.y)
   
End Sub 'SendMouseClickToButton'

I converted the coordinates to pixels for SetCursorPos.


From MSDN:

dx = Specifies the mouse's absolute position along the x-axis or its amount of motion since the last mouse event was generated
dy = Specifies the mouse's absolute position along the y-axis or its amount of motion since the last mouse event was generated

Does SetCursorPos count as a mouse event?


Bob
0
 
LVL 96

Author Comment

by:Bob Learned
ID: 11916645
I went with the KISS principal instead.  

I took from your suggestion to use a regular menu that I could do a popup that would look like the button's drop down menu.  I got a bonus, because it also gave me the ability to use the Checked property to show which option is currently selected, which the ButtonMenu doesn't have.  I just used the tbrDropDown style for the button to give me the drop down button, but didn't add any ButtonMenus; I just added menu options to a hidden menu.

I wasn't seeing the forest for the trees:)  I was stuck trying to make something work, without going outside of the box, so thank you very much for helping push me in the needed direction.

Bob
0
 
LVL 49

Expert Comment

by:Ryan Chong
ID: 11919443
>>cButt and dwEI
I checked back to the original source, cButt and dwEI is not declared, so they should be as 0, sorry bout that..

>>Does SetCursorPos count as a mouse event?
I don't think so, it just set the cursor to the position we desired...

>>because it also gave me the ability to use the Checked property to show which option is currently selected
That's great ;-)

Glad could make help here 8-) cheers
0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

There are many ways to remove duplicate entries in an SQL or Access database. Most make you temporarily insert an ID field, make a temp table and copy data back and forth, and/or are slow. Here is an easy way in VB6 using ADO to remove duplicate row…
This article describes some techniques which will make your VBA or Visual Basic Classic code easier to understand and maintain, whether by you, your replacement, or another Experts-Exchange expert.
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

759 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now