How to crash the Listbox …

Well, I decided to file a bug report again - let’s see if it does any better than the previous ones:

OutOfBounds Exception in HeaderBackgroundPaint event as g.width is ZERO
feedback://showreport?report_id=61965

All the code you need is

Dim p As New Picture(g.Width, g.Height)

in the HeaderBackgroundPaint event and you will get an OutOfBounds exception as g.width is 0.0

Setting the Listbox count to 1 and the width to 1* does not help, you need to set the Listbox width to a literal (eg 100).

Why is g.width ZERO in the first place???

Kind of cements my impression that the customisable header was a last minute addition and not well thought out and implemented.

The bug has an easy workaround. This will be fixed in 10 years.

2 Likes

If you set the Font size to 30 then the Header height will be 40. This is insane! How are you supposed to precisely set your header height? By guessing? Trial & error? Why not:

Fig 2 User-friendly header and row settings for the ListBox

After all, backwards compatibility has been thrown out of the window anyway, so why stop now?

And btw, you COULD implement this in a backward-compatible way - the Listbox has HeaderHeight and RowHeight properties since 2009 - but they are read only! Why not implement them as they should be implemented???

I’ll be damned - now it is no longer doing it.

I didn’t even restart, it is the same unchanged project.

And it’s back. I emptied the cache and then it was back - how???

I would understand if it was the other way round but this …???

Ok - got it:

I changed the code a bit and followed it in the debugger and the Exception happens on the second entry with column = 1

But there is only one column, column 0 - so of course g.width is zero, but that is not allowed.

While checking for g.width solves the crashing problem there is another one: the stub problem - in my case it is 15 pixel wide and I would guess that it is space reserved for the scrollbar.

I can show that it is definitely the scrollbar showing up as in that case another column the width of the scrollbar is being added - and I can paint in that additional column! (which seems a really weird way of dealing with the problem - I would have thought the Listbox is more modular internally, maybe a ContainerControl that draws the header in the paint event of the ContainerControl and adds a scrollbar beside the rows if necessary).

If I use a hierarchical Listbox with all folders collapsed then I do not see the stub:

screenshot_149

but if I expand a folder and the scrollbar shows up then I see it:

screenshot_150

I can actually paint in the stub by doing

If g Is Nil Or g.width = 0 Then Return False

Me.CreatePictureOfGradient( g )
g.DrawPicture(Me.PictureOfGradient, 0, 0, g.width, g.height, 0, 0, 1, g.height)

If column < me.ColumnCount Then
  // do your other custom drawing 
end if 

Return True

screenshot_151

So the final answer is to do:

If g Is Nil Or g.width = 0 Then Return False

// For the background I create a gradient that is 1 pixel wide and g.height high
Me.CreatePictureOfGradient( g ) 
// and paint that across g
g.DrawPicture(Me.PictureOfGradient, 0, 0, g.width, g.height, 0, 0, 1, g.height)

If column < me.ColumnCount Then
  // do your other custom drawing 
end if 

Return True

My thanks to Jeremy and BEATRIX (!) :hugs:

The listbox has slowly evolved over the last 20+ years and is a beast
Ask anyone who has ever had to touch the C++ internals

Its one of those controls that probably needs a rewrite
Some have suggested splitting it into several - but then that make programmatically switching from a hierarchical to non-hierarchical and back troublesome

Problem is that its a big control with lots of behaviours
And rewriting such a big control IS painful
And splitting it into several others causes new issues

Dunno what the right answer for it is