Tip 76: Detecting Right Mouse Button Clicks on List Box Controls

 VB-CODE (2)

Abstract
When using a List Box control in a Visual Basic® application, the user
can click on an item with the left mouse button. That item then
becomes selected. This article explains how you can select items with
the right mouse button instead of the left mouse button.

Intercepting Right Mouse Button Click Events
The LB_GETITEMRECT message can be used to determine which item in a
List Box was selected. This message retrieves the coordinates of a
bounding rectangle for the selected item in the List Box control. To
invoke this message, you must tell it the entry number, starting at
zero, whose dimensions you want to retrieve, as well as a RECT
structure that will hold the coordinate information.

To determine which item a user clicked on with the right mouse button,
you trap the MouseUp event. The MouseUp event can be used to determine
which mouse button was pressed and the mouse's current X and Y
coordinates on the form or control.
Once we have determined the mouse's position over the List Box control,
we can use the Windows® application programming interface (API)
SendMessage function to return the index number of the item the mouse
was positioned over when the MouseUp event was triggered.

Example Program
The example program below displays a List Box control on a form.
Whenever you click the right mouse button on an item in the List Box,
the message "Right Click on" is displayed in the Text Box along with
the index number corresponding to the selected item.

1. Create a new project in Visual Basic. Form1 is created by default.
2. Add the following code to the Form_Load event for Form1:

Private Sub Form_Load()
List1.AddItem "Item #1"
List1.AddItem "Item #2"
List1.AddItem "Item #3"
End Sub

3. Add a List Box control to Form1. List1 is created by default.
4. Add the following code to the MouseUp event for List1 (note that
the Private lines must be typed as a single line of code):

Private Sub List1_MouseUp(Button As Integer, Shift As Integer,
X As Single, Y As Single)
Dim Item%
If (Button = 2) Then
Item% = GetRClickedItem(List1, X, Y)
If (Item% = LB_ERR) Then
Text1.Text = "ERROR"
Else
Text1.Text = "Right Click on " + Str(Item%)
End If
End If
End Sub

5. Add a Text Box control to Form1. Text1 is created by default.
6. Add a new module to the project. Module.Bas is created by default.
7. Add the following code to the Module.Bas file (note that the
Private and If lines must be typed as a single line of code):

Type RECT
Left As Integer
Top As Integer
Right As Integer
Bottom As Integer
End Type

Global Const WM_USER = &H400
Global Const LB_GETITEMRECT = (WM_USER + 25)
Global Const LB_ERR = (-1)

Private Declare Function SendMessage Lib "User" (ByVal hWnd
As Integer, ByVal wMsg As Integer, ByVal wParam
As Integer, lParam As Any) As Long
Function GetRClickedItem%(MyList As Control, X As Single, Y As Single)

Dim ClickX%, ClickY%, Ret&, CurRect As RECT
ClickX% = X \ Screen.TwipsPerPixelX
ClickY% = Y \ Screen.TwipsPerPixelY
i% = 0
Do While True
Ret& = SendMessage(MyList.hWnd, LB_GETITEMRECT, i%, CurRect)
If (Ret& = LB_ERR) Then
GetRClickedItem% = LB_ERR: Exit Function
End If
If (ClickX% >= CurRect.Left) And (ClickX% <= CurRect.Right) And (ClickY% >= CurRect.Top) And (ClickY% <= CurRect.Bottom) Then GetRClickedItem% = i%: Exit Function End If i% = i% + 1 Loop End Function Additional References Programmer's Reference Volume 3: Messages, Structures. "LB_GETITEMRECT". (Product Documentation, SDKs, Windows 3.1 SDK) "List Box Controls." (Technical Articles, Windows Articles, User Interface Articles, Controls) "MouseDown, MouseUp Events". (Product Documentation, Office Developer's Kit 1.0, Visual Basic 3.0 Professional Edition, Language Reference)

No comments: