From 84dc4707d7ce536b1013b91d89692c7dc9aa83c7 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 22 Apr 2019 14:57:55 +0200 Subject: [PATCH] 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. --- include/wx/msw/checklst.h | 2 ++ include/wx/msw/listbox.h | 7 +++++++ src/msw/checklst.cpp | 36 ++++++++++++++++++------------------ src/msw/listbox.cpp | 3 +++ 4 files changed, 30 insertions(+), 18 deletions(-) diff --git a/include/wx/msw/checklst.h b/include/wx/msw/checklst.h index 6f1e7a88ae..8fa50253ba 100644 --- a/include/wx/msw/checklst.h +++ b/include/wx/msw/checklst.h @@ -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); diff --git a/include/wx/msw/listbox.h b/include/wx/msw/listbox.h index 961e78b2b3..3ba0175320 100644 --- a/include/wx/msw/listbox.h +++ b/include/wx/msw/listbox.h @@ -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(); diff --git a/src/msw/checklst.cpp b/src/msw/checklst.cpp index f6c3300232..753bccc335 100644 --- a/src/msw/checklst.cpp +++ b/src/msw/checklst.cpp @@ -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(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(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(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 diff --git a/src/msw/listbox.cpp b/src/msw/listbox.cpp index 296447c61e..47d54e985e 100644 --- a/src/msw/listbox.cpp +++ b/src/msw/listbox.cpp @@ -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 }