diff --git a/include/wx/msw/combobox.h b/include/wx/msw/combobox.h index 5fc7cc5cf1..449eb17266 100644 --- a/include/wx/msw/combobox.h +++ b/include/wx/msw/combobox.h @@ -126,6 +126,8 @@ public: virtual bool SetHint(const wxString& hint); #endif // wxUSE_UXTHEME + virtual void SetLayoutDirection(wxLayoutDirection dir) wxOVERRIDE; + protected: #if wxUSE_TOOLTIPS virtual void DoSetToolTip(wxToolTip *tip); diff --git a/include/wx/msw/private.h b/include/wx/msw/private.h index 5632e4e241..de77f43125 100644 --- a/include/wx/msw/private.h +++ b/include/wx/msw/private.h @@ -1013,29 +1013,28 @@ inline long wxSetWindowExStyle(const wxWindowMSW *win, long style) return ::SetWindowLong(GetHwndOf(win), GWL_EXSTYLE, style); } -// Update layout direction flag for an EDIT control. -// -// Returns true if anything changed or false if the direction flag was already -// set to the desired direction (which can't be wxLayout_Default). -inline bool wxUpdateEditLayoutDirection(WXHWND hWnd, wxLayoutDirection dir) +// Common helper of wxUpdate{,Edit}LayoutDirection() below: sets or clears the +// given flag(s) depending on wxLayoutDirection and returns true if the flags +// really changed. +inline bool +wxUpdateExStyleForLayoutDirection(WXHWND hWnd, + wxLayoutDirection dir, + LONG_PTR flagsForRTL) { wxCHECK_MSG( hWnd, false, wxS("Can't set layout direction for invalid window") ); - static const LONG_PTR - EDIT_RTL_EX_FLAGS = WS_EX_RIGHT | WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR; - const LONG_PTR styleOld = ::GetWindowLongPtr(hWnd, GWL_EXSTYLE); LONG_PTR styleNew = styleOld; switch ( dir ) { case wxLayout_LeftToRight: - styleNew &= ~EDIT_RTL_EX_FLAGS; + styleNew &= ~flagsForRTL; break; case wxLayout_RightToLeft: - styleNew |= EDIT_RTL_EX_FLAGS; + styleNew |= flagsForRTL; break; case wxLayout_Default: @@ -1050,6 +1049,28 @@ inline bool wxUpdateEditLayoutDirection(WXHWND hWnd, wxLayoutDirection dir) return true; } +// Update layout direction flag for a generic window. +// +// See below for the special version that must be used with EDIT controls. +// +// Returns true if the layout direction did change. +inline bool wxUpdateLayoutDirection(WXHWND hWnd, wxLayoutDirection dir) +{ + return wxUpdateExStyleForLayoutDirection(hWnd, dir, WS_EX_LAYOUTRTL); +} + +// Update layout direction flag for an EDIT control. +// +// Returns true if anything changed or false if the direction flag was already +// set to the desired direction (which can't be wxLayout_Default). +inline bool wxUpdateEditLayoutDirection(WXHWND hWnd, wxLayoutDirection dir) +{ + return wxUpdateExStyleForLayoutDirection(hWnd, dir, + WS_EX_RIGHT | + WS_EX_RTLREADING | + WS_EX_LEFTSCROLLBAR); +} + // Companion of the above function checking if an EDIT control uses RTL. inline wxLayoutDirection wxGetEditLayoutDirection(WXHWND hWnd) { diff --git a/src/msw/combobox.cpp b/src/msw/combobox.cpp index 02dfefb82b..f846184d63 100644 --- a/src/msw/combobox.cpp +++ b/src/msw/combobox.cpp @@ -707,4 +707,38 @@ wxWindow *wxComboBox::MSWFindItem(long id, WXHWND hWnd) const return wxChoice::MSWFindItem(id, hWnd); } +void wxComboBox::SetLayoutDirection(wxLayoutDirection dir) +{ +#ifndef __WXWINCE__ + // Edit field and drop-down list must be handled explicitly. + + // Edit field is a special EDIT control (e.g. it always returns null + // extended style flags), so its layout direction should be set using the + // same extended flag as for ordinary window but reset simply with + // alignment flags. + if ( dir == wxLayout_RightToLeft ) + { + wxUpdateLayoutDirection(GetEditHWND(), dir); + } + else + { + LONG_PTR style = ::GetWindowLongPtr(GetEditHWND(), GWL_STYLE); + if ( !(style & ES_CENTER) ) + { + style &= ~ES_RIGHT; + ::SetWindowLongPtr(GetEditHWND(), GWL_STYLE, style); + } + } + + // Layout for the drop-down list also must be set explicitly. + WinStruct info; + if ( ::GetComboBoxInfo(GetHwnd(), &info) ) + { + wxUpdateLayoutDirection(info.hwndList, dir); + } +#endif // !__WXWINCE__ + + wxChoice::SetLayoutDirection(dir); +} + #endif // wxUSE_COMBOBOX diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 3d4dae58fd..ccca4f7a90 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -1135,31 +1135,8 @@ void wxWindowMSW::SetLayoutDirection(wxLayoutDirection dir) #ifdef __WXWINCE__ wxUnusedVar(dir); #else - wxCHECK_RET( GetHwnd(), - wxT("layout direction must be set after window creation") ); - - LONG styleOld = wxGetWindowExStyle(this); - - LONG styleNew = styleOld; - switch ( dir ) + if ( wxUpdateLayoutDirection(GetHwnd(), dir) ) { - case wxLayout_LeftToRight: - styleNew &= ~WS_EX_LAYOUTRTL; - break; - - case wxLayout_RightToLeft: - styleNew |= WS_EX_LAYOUTRTL; - break; - - default: - wxFAIL_MSG(wxT("unsupported layout direction")); - break; - } - - if ( styleNew != styleOld ) - { - wxSetWindowExStyle(this, styleNew); - // Update layout: whether we have children or are drawing something, we // need to redo it with the new layout. SendSizeEvent();