From 0d04792116c3c2cb715e538981738db7e7090d76 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 29 Jan 2021 01:33:13 +0100 Subject: [PATCH] Show full text in single line MSW wxTextCtrl if possible A single line MSW wxTextCtrl created with a value too long to fit into it continued showing the value only partially even if its size was subsequently increased to allow the entire value to be shown. This apparently happens because changing the native EDIT control size doesn't affect its (horizontal) scroll offset. Moreover, there doesn't seem to be any way to explicitly tell the control to update it neither, except for changing its text. So do change its text every time its width changes, as long as it is not visible (because visible jumps in the visible text position could be an even worse problem than the one we're trying to solve here). This fixes the originally reported bug at the cost of a bunch of extra calls to DoWriteText() which should hopefully be not too expensive for single line controls that don't typically contain that much text. Closes #18268. --- include/wx/msw/textctrl.h | 2 ++ src/msw/textctrl.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/include/wx/msw/textctrl.h b/include/wx/msw/textctrl.h index 7a804e2617..21f5a79c76 100644 --- a/include/wx/msw/textctrl.h +++ b/include/wx/msw/textctrl.h @@ -241,6 +241,8 @@ protected: virtual wxSize DoGetBestSize() const wxOVERRIDE; virtual wxSize DoGetSizeFromTextSize(int xlen, int ylen = -1) const wxOVERRIDE; + virtual void DoMoveWindow(int x, int y, int width, int height) wxOVERRIDE; + #if wxUSE_RICHEDIT virtual void MSWUpdateFontOnDPIChange(const wxSize& newDPI) wxOVERRIDE; diff --git a/src/msw/textctrl.cpp b/src/msw/textctrl.cpp index 6991eb79bb..7156658d38 100644 --- a/src/msw/textctrl.cpp +++ b/src/msw/textctrl.cpp @@ -2639,6 +2639,30 @@ wxSize wxTextCtrl::DoGetSizeFromTextSize(int xlen, int ylen) const return wxSize(wText, hText); } +void wxTextCtrl::DoMoveWindow(int x, int y, int width, int height) +{ + // We reset the text of single line controls each time their width changes + // because they don't adjust their horizontal offset on their own and there + // doesn't seem to be any way to convince them to do it other than by just + // setting the text again, see #18268. + const bool resetText = IsSingleLine() && !IsShownOnScreen(); + int oldWidth = -1; + if ( resetText ) + { + oldWidth = GetSize().x; + } + + wxTextCtrlBase::DoMoveWindow(x, y, width, height); + + if ( resetText && GetSize().x != oldWidth ) + { + // We need to use DoWriteText() to avoid our own optimization in + // ChangeValue() which does nothing when the text doesn't really + // change. + DoWriteText(DoGetValue(), 0 /* no flags for no events */); + } +} + // ---------------------------------------------------------------------------- // standard handlers for standard edit menu events // ----------------------------------------------------------------------------