Solved

Windows Common Controls:  Toolbar Button with Drop Menu

Posted on 2004-08-26
12
675 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 51

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 51

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
Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 51

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 51

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
 
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 51

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

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

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…
I’ve seen a number of people looking for examples of how to access web services from VB6.  I’ve been using a test harness I built in VB6 (using many resources I found online) that I use for small projects to work out how to communicate with web serv…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
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…

837 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