Visual Basic List API Routines
SendMessage: Right-Click List Item Selection
     
Posted:   Wednesday April 21, 1999
Updated:   Monday December 26, 2011
     
Applies to:   VB4-32, VB5, VB6
Developed with:   VB6, Windows NT4
OS restrictions:   None
Author:   VBnet - Randy Birch
     

Related:  

LBItemFromPt: Right-Click List Item Selection
LBItemFromPt: Right-Click List Item Selection from Any Routine
     
 Prerequisites
None.

After experimenting with a variety of advanced list-type controls, it seems more and more developers are turning back to the trusty listbox to display simple data, yet want some of the functionality that other provided and third-party controls offer.  Once such case is the desire to determine the list item over which a right-mouse button was clicked, often to display a context menu tailored for the specific item, or simply as an aid in selecting the item via either button.

By using SendMessage, CopyMemory, a couple of C-macros, and the LB_ITEMFROMPOINT message, determining the list item is a straightforward process.

 BAS Module Code
None.

 Form Code
Add a listbox (List1), a textbox (Text1) and a command button (Command1) to a form, and add the following code:

Option Explicit
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Copyright 1996-2011 VBnet/Randy Birch, All Rights Reserved.
' Some pages may also contain other copyrights by the author.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Distribution: You can freely use this code in your own
'               applications, but you may not reproduce 
'               or publish this code on any web site,
'               online service, or distribute as source 
'               on any media without express permission.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Type POINTAPI
   X As Long
   Y As Long
End Type

Private Const LB_ITEMFROMPOINT As Long = &H1A9

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

Private Declare Sub CopyMemory Lib "kernel32" _
   Alias "RtlMoveMemory" _
  (Destination As Any, Source As Any, _
   ByVal Length As Long)

Private Declare Function GetCursorPos Lib "user32" _
  (lpPoint As POINTAPI) As Long

Private Declare Function ScreenToClient Lib "user32" _
  (ByVal hWnd As Long, _
   lpPoint As POINTAPI) As Long


Private Sub Command1_Click()

   Unload Me
   
End Sub


Private Sub Form_Load()

 'Add a few items
  Dim i As Integer
  
   For i = 0 To 20
      List1.AddItem "List item no" & Str$(i)
   Next
   
End Sub


Public Function LoWord(dwValue As Long) As Integer

  CopyMemory LoWord, dwValue, 2
  
End Function


Public Function MAKELONG(wLow As Long, wHigh As Long) As Long

  MAKELONG = LoWord(wLow) Or (&H10000 * LoWord(wHigh))
  
End Function


Public Function MAKELPARAM(wLow As Long, wHigh As Long) As Long

 'Combines two integers into a long integer
  MAKELPARAM = MAKELONG(wLow, wHigh)
  
End Function


Private Sub List1_MouseDown(Button As Integer, _
                            Shift As Integer, _
                            X As Single, Y As Single)

   If Button = vbRightButton Then
      
      Dim lParam As Long
      Dim curritem As Long
      Dim r As Long
      Dim pt As POINTAPI
      
      Call GetCursorPos(pt)
      Call ScreenToClient(List1.hWnd, pt)
      
      lParam = MAKELPARAM(pt.X, pt.Y)
                              
      r = SendMessage(List1.hWnd, _
                      LB_ITEMFROMPOINT, _
                      0&, ByVal lParam)
      
      If r > -1 Then
         curritem = LoWord(r)
         Text1.Text = "Right-mouse clicked over item " & _
                       curritem & " - " & vbTab & Chr$(34) & _
                       List1.List(curritem) & Chr$(34)
         
        'this line selects the item (if desired) 
        'with the right-click
         List1.Selected(curritem) = True
        
        'uncomment to display a context menu which 
        'could be customized for the given selection
        'PopupMenu mnuListOptions
      End If
      
   End If
   
End Sub
 Comments
Run the project and right-click a list item .... it will become selected, and its index and text will be reflected in the listbox.

By moving or copying the code to the List1_MouseMove event, removing the If .. Then statement, and commenting out the List1.Selected() statement, the textbox will now reflect the item the mouse is currently over - (as opposed to selected) - great for displaying in a status bar.


 
 

PayPal Link
Make payments with PayPal - it's fast, free and secure!

 
 
 
 

Copyright 1996-2011 VBnet and Randy Birch. All Rights Reserved.
Terms of Use  |  Your Privacy

 

Hit Counter