Fix rare crash when using native header in wxGrid under MSW

Pressing Esc while double clicking on the column separator in the native
header in wxGrid could result in a crash due to using invalid index when
calling GetColLeft(m_dragRowOrCol) in GetPositionForResizeEvent() called
from DoHeaderEndDragResizeCol() because m_dragRowOrCol had been already
reset to -1.

Guard against the crash with a check in GetPositionForResizeEvent()
itself and also add a check to DoHeaderDragResizeCol() to avoid calling
the former function in this case.

Reproducing the original problem is relatively simple as it's enough to
just keep double clicking a column separator while also pressing Esc,
but catching it under debugger is much more complicated and so it's not
really clear how exactly does this happen, but tracing shows that the
native control just decides to generate two HDN_ENDTRACK messages
without any intervening HDN_BEGINTRACK, so it doesn't seem like we can
do anything else than just silently ignore the unwanted HDN_ENDTRACK, as
it's done in this commit.
This commit is contained in:
Vadim Zeitlin
2020-06-27 01:42:57 +02:00
parent 04f4ac32b1
commit b7e7bb763a

View File

@@ -4892,6 +4892,9 @@ void wxGrid::DoGridDragResize(const wxPoint& position,
wxPoint wxGrid::GetPositionForResizeEvent(int width) const
{
wxCHECK_MSG( m_dragRowOrCol != -1, wxPoint(),
"shouldn't be called when not drag resizing" );
// Note that we currently always use m_gridWin here as using
// wxGridHeaderCtrl is incompatible with using frozen rows/columns.
// This would need to be changed if they're allowed to be used together.
@@ -4935,6 +4938,14 @@ void wxGrid::DoHeaderDragResizeCol(int width)
void wxGrid::DoHeaderEndDragResizeCol(int width)
{
// We can sometimes be called even when we're not resizing any more,
// although it's rather difficult to reproduce: one way to do it is to
// double click the column separator line while pressing Esc at the same
// time. There seems to be some kind of check for Esc inside the native
// header control and so an extra "end resizing" message gets generated.
if ( m_dragRowOrCol == -1 )
return;
// Unfortunately we need to create a dummy mouse event here to avoid
// modifying too much existing code. Note that only position and keyboard
// state parts of this event object are actually used, so the rest