Fix horizontal scrollbar handling for wxCheckListBox in wxMSW

The scrollbar wasn't shown when the control became only slightly more
narrow than its contents, resulting in truncation of the rightmost part
of the strings shown in it.

Fix this by accounting for the check box explicitly in wxListBox
SetHorizontalExtent() method using the new MSWGetFullItemSize() helper
which is also used to avoid code duplication between wxCheckListBox
MSWOnMeasure() and DoGetBestClientSize() methods.

Closes #18377.
This commit is contained in:
Vadim Zeitlin
2019-04-22 14:57:55 +02:00
parent 96422fde4d
commit 84dc4707d7
4 changed files with 30 additions and 18 deletions

View File

@@ -65,6 +65,8 @@ public:
virtual bool MSWOnMeasure(WXMEASUREITEMSTRUCT *item) wxOVERRIDE;
protected:
virtual wxSize MSWGetFullItemSize(int w, int h) const wxOVERRIDE;
// pressing space or clicking the check box toggles the item
void OnKeyDown(wxKeyEvent& event);
void OnLeftClick(wxMouseEvent& event);

View File

@@ -174,6 +174,13 @@ protected:
// this can't be called DoHitTest() because wxWindow already has this method
virtual int DoHitTestList(const wxPoint& point) const;
// This is a hook for wxCheckListBox, which uses it to add the checkbox
// width to the item width and to make it at least as tall as the checkbox.
virtual wxSize MSWGetFullItemSize(int w, int h) const
{
return wxSize(w, h);
}
// free memory (common part of Clear() and dtor)
void Free();

View File

@@ -246,15 +246,10 @@ bool wxCheckListBox::MSWOnMeasure(WXMEASUREITEMSTRUCT *item)
{
MEASUREITEMSTRUCT *pStruct = (MEASUREITEMSTRUCT *)item;
wxSize size = wxRendererNative::Get().GetCheckBoxSize(this);
size.x += 2 * CHECKMARK_EXTRA_SPACE;
size.y += 2 * CHECKMARK_EXTRA_SPACE;
// add place for the check mark
pStruct->itemWidth += size.GetWidth();
if ( pStruct->itemHeight < static_cast<unsigned int>(size.GetHeight()) )
pStruct->itemHeight = size.GetHeight();
const wxSize size = MSWGetFullItemSize(pStruct->itemWidth,
pStruct->itemHeight);
pStruct->itemWidth = size.x;
pStruct->itemHeight = size.y;
return true;
}
@@ -422,20 +417,25 @@ void wxCheckListBox::OnLeftClick(wxMouseEvent& event)
}
}
wxSize wxCheckListBox::MSWGetFullItemSize(int w, int h) const
{
wxSize size = wxRendererNative::Get().GetCheckBoxSize(const_cast<wxCheckListBox*>(this));
size.x += 2 * CHECKMARK_EXTRA_SPACE;
size.y += 2 * CHECKMARK_EXTRA_SPACE;
w += size.GetWidth();
if ( h < size.GetHeight() )
h = size.GetHeight();
return wxSize(w, h);
}
wxSize wxCheckListBox::DoGetBestClientSize() const
{
wxSize best = wxListBox::DoGetBestClientSize();
// add room for the checkbox
wxSize size = wxRendererNative::Get().GetCheckBoxSize(const_cast<wxCheckListBox*>(this));
size.x += 2 * CHECKMARK_EXTRA_SPACE;
size.y += 2 * CHECKMARK_EXTRA_SPACE;
best.x += size.GetWidth();
if ( best.y < size.GetHeight() )
best.y = size.GetHeight();
return best;
return MSWGetFullItemSize(best.x, best.y);
}
#endif // wxUSE_CHECKLISTBOX

View File

@@ -596,7 +596,10 @@ void wxListBox::SetHorizontalExtent(const wxString& s)
}
if ( largestExtent )
{
largestExtent = MSWGetFullItemSize(largestExtent, 0 /* height */).x;
SendMessage(GetHwnd(), LB_SETHORIZONTALEXTENT, LOWORD(largestExtent), 0L);
}
//else: it shouldn't change
}