Bad row number from listbox.RowFromXY

I’ve had this code in a listbox’s double-click handler for over two years, without any issues. This listbox is top-left within the window. Today, I get an exception.

// Handler used when a mail is double-clicked in the mailbox list

Var  row As Integer, mrd As mailrowData

row = me.RowFromXY (me.MouseX, me.MouseY)
mrd = me.RowTagAt(row)

openMail (mrd.origabsid, mrd.origmboxid)

Here is a part of the stack trace (which I log):

12 Mar 2020 19:22:20 FATAL: Stack: RuntimeRaiseException
12 Mar 2020 19:22:20 FATAL: RaiseOutOfBoundsException
12 Mar 2020 19:22:20 FATAL: ListGetRowTag
12 Mar 2020 19:22:20 FATAL: Listbox.RowTagAt%v%oi8
12 Mar 2020 19:22:20 FATAL: MainWindow.MainWindow.MailsList_DoubleClick%%o<MainWindow.MainWindow>o
12 Mar 2020 19:22:20 FATAL: Delegate.IM_Invoke%%o
12 Mar 2020 19:22:20 FATAL: AddHandler.Stub.27%%
12 Mar 2020 19:22:20 FATAL: _ZN9NuListbox11HandleClickERK10MouseEvent
12 Mar 2020 19:22:20 FATAL: XojoFramework$5296
12 Mar 2020 19:22:20 FATAL: XojoFramework$5160
12 Mar 2020 19:22:20 FATAL: -[NSWindow(NSEventRouting) _handleMouseDownEvent:isDelayedEvent:]
12 Mar 2020 19:22:20 FATAL: -[NSWindow(NSEventRouting) _reallySendEvent:isDelayedEvent:]
12 Mar 2020 19:22:20 FATAL: -[NSWindow(NSEventRouting) sendEvent:]

Of course I should be checking the row number I get, but is there anything in the code to suppose that double-clicking a listbox row could lead to a bad row number?

From the docs:

The parameters X and Y are relative to the top, left corner of the ListBox . If you use System.MouseX or System.MouseY to get the mouse coordinates to use with this method, you’ll need to take into account that those System values are relative to the top-left corner of the entire screen.

Your code looks to be using System.MouseX?

Where did you click - outside of the available rows? And yes, a check for row <> -1 would be good.

Why not use the DoubleClick event?

He is using the Listbox.DoubleClick event, as he stated and as the stack trace shows.

Though the docs don’t mention it in the DoubleClick or RowFromXY sections, there is this in CellBackgroundPaint:

CellBackgroundPaint fires for every visible row in a ListBox, regardless of whether there is an actual row there or not. This enables you to implement the background paint event for the entire ListBox in a consistent way. For example, to do alternating row colors. Because of this, you need to check whether the current row is less than RowCount when accessing the row , for example with the Cell method.

It would require some testing to confirm, but a guess is that RowFromXY sort of does the same thing if you double-click on the “blank” area beyond the last row. So you may need to not only check for row <> -1 as Beatrix wrote, but also that row <= LastRowIndex (or < ListCount for API 1).

No, it uses the listbox’s MouseX and MouseY properties. It may be, however, that this works only because the listbox has top=0 and left=0.

As you see from my OP, at the minute I don’t check the row number. So far this has not proved to be a problem even when clicking beyond the “real” rows in a listbox. I had already added a check for row against -1 and LastRowIndex before posting my OP - and I shall be logging any “bad” values, too. I’m inclined to suspect a rare timing issue with events. I’ll also do a bit of testing to see if the double-click event fires when clicking beyond the last real row.

After testing: OK, double-click doesn’t appear to fire if you click in the blank rows after the last real row.

Hmm, that is interesting, as is the fact that you haven’t had this error for over two years until now.

It would be great if you were able to ascertain exactly what condition(s) produce an invalid value. You should log the X & Y and the row values. If possible, also what had focus when the double-click occurred.