I found, using a DataGrid control in VB6 there is no property you can query in any of the events which tells you the row you have clicked on when you are using the right button of the mouse.
You might need that for right-click menus or other features you would like to add.
The following method will determine which of the rows you have clicked on (using the right mouse button), derived from the Y-Coordinates as passed for example from the Mouse_Down event.
After the code below I go more into detail why I'm using certain parameters and logic. I have used the shown method in several applications and never had any incorrect rows returned or users reporting any issues.
VB Code:
'/// <summary>Determines the selected row, derived from the Y position in the grid.</summary>
'/// <param name="gridRowHeight">The height of the rows in the grid.</param>
'/// <param name="gridBorderWidth">The width of the border between the rows.</param>
'/// <param name="y">The y-coordinate the mouse was clicked within the grid.</param>
'/// <param name="gridHasHeaderRow">Indicates whether the grid has a header row or not.</param>
'/// <param name="headerLineCount">The count of header-lines on the grid.</param>
'/// <returns>
'/// Returns the positional number of the selected row or -1 if the
'/// selection (y) was made in an invalid area or an error has occurred.
'/// </returns>
Public Function GetSelectedDataGridRowByY( _
gridRowHeight As Integer, gridBorderWidth As Integer, y As Single, _
gridHasHeaderRow As Boolean, headerLineCount As Integer) As Integer
'/// <summary>Stores the return value.</summary>
Dim returnValue As Integer
'/// <summary>Stores the height of the header row.</summary>
Dim headerRowHeight As Integer
'/// <summary>Stores selected row, not taking into account any borders.</summary>
Dim approximateSelectedRow As Double
'/// <summary>Stores the number of borders to deduct.</summary>
Dim numberOfBorders As Integer
'/// <summary>Stores the actual selected row after borders have been deducted.</summary>
Dim exactSelectedRow As Integer
'/// <summary>The exact Y value after deduction borders and header row.</summary>
Dim exactY As Integer
If gridHasHeaderRow Then
headerRowHeight = (225 * headerLineCount)
exactY = (y - headerRowHeight)
Else
exactY = y
End If
approximateSelectedRow = (exactY / gridRowHeight)
numberOfBorders = Round(approximateSelectedRow - 0.5)
approximateSelectedRow = _
((exactY - ((numberOfBorders) * gridBorderWidth)) / gridRowHeight)
exactSelectedRow = Round(approximateSelectedRow - 0.5)
If ((exactSelectedRow >= 0) And (exactY >= 0)) Then
returnValue = exactSelectedRow
Else
returnValue = -1
End If
Finally:
GetSelectedDataGridRowByY = returnValue
Exit Function
Catch:
returnValue = -1
Resume Finally
End Function
This is how you might use the code:
VB Code:
'/// <summary>
'/// Occurs when mouse has been pressed down on DataGrid1.
'/// </summary>
Private Sub DataGrid1_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
If Button = vbRightButton Then
'/// <summary>Stores the positional number of the selected row.</summary>
Dim newRow As Integer
'/// <summary>Stores the borderwidth of the grid-lines in the DataGrid.</summary>
Const borderWidthInTwips As Integer = 13
newRow = GetSelectedDataGridRowByY(DataGrid1.RowHeight, borderWidthInTwips, y, True, DataGrid1.HeadLines)
MsgBox "Row number: " & newRow & " has been clicked."
End If
End Sub
Code Details
The basic idea is to take the y-coordinate the mouse has been clicked on in the DataGrid and divide that number by the height of the rows. Just doing that though will create discrepancies in DataGrids with a lot of Rows. This is due to the border in-between each row. In addition I decided not to include the header row in the process, if it has been indicated that a header row exists to ensure the header stays neutral. Feel free though to add a parameter to allow the developer to specify this generically instead.
The code above will re-calculate the y-coordinate to the “true” y coordinates in case a header has been included and selected. In addition the number of borders are determined and their height is deducted from y as well. Thus at the end the exact y coordinate, divided by the height of the rows will get the exact row selected.
Additional Notes
A note on the headerLineCount parameter and the headerRowHeight variable. There is a property on the DataGrid named “HeadLines” which determines how many rows high the header-row is. The exact row height seems fixed though, meaning the header row will always be 225 twips (15pixels) per HeadLine.
Another note on the '13' borderwidth; That is what worked best for me as border width. The borderwidth in a DataGrid seems to be just under a full pixel. A full pixel is 15 twips but I did get slight discrepencies when clicking near borders further down the grid. This however could have been a graphical glitch. If 15 works for you better then use 15 instead.