3

I'm trying to create a dynamic dialog, which can be made RTL depending on the language. But I have the following issue: whenever I change the RTL style of the combo box, the text comes up reversed. I tried using functions such as InvalidateRect, RedrawWindow, etc., but couldn't make it work correctly.

Relevant code (WinAPI with WTL):

CComboBox combo = hWndCtl;
if(combo.GetCurSel() == 0)
    combo.ModifyStyleEx(WS_EX_LAYOUTRTL, 0);
else
    combo.ModifyStyleEx(0, WS_EX_LAYOUTRTL);

A demo project: here.

A demonstration of the issue:

enter image description here

Paul
  • 6,061
  • 6
  • 39
  • 70
  • **This is not an answer; it is a diagnosis. If the answer is "it redraws correctly", then the suggestion here should not be taken as "the answer", but proves an idea that I have about what's going on based on prior experience.**: what happens if you call `InvalidateRect()` in the handler for, say, `WM_USER+5` in your parent window's window procedure, and call `PostMessage(parent window, WM_USER+5, 0, 0)` or similar after changing the extended style? Does it redraw correctly, or does it stay flipped? – andlabs Aug 19 '16 at 14:53

1 Answers1

2

It seems you are responding to CBN_SELCHANGE notification. This is notification is sent after combobox sets the text in its editbox.

You should respond to CBN_SELENDOK instead. CBN_SELENDOK is sent before CBN_SELCHANGE, this gives you time to modify the style before combobox sets the text.

switch (HIWORD(wParam))
{
case CBN_SELENDOK:// CBN_SELCHANGE:
    if (SendMessage(hComboBox, CB_GETCURSEL, 0, 0) == 0)
        ModifyStyleEx(hComboBox, WS_EX_LAYOUTRTL, 0);
    else
        ModifyStyleEx(hComboBox, 0, WS_EX_LAYOUTRTL);
    break;
default:break;
}



Edit: Windows 10 has fade in/out effect. If you change the combo selection with keyboard, while the color is fading, the text is still goes backward.

ComboBox has an edit control which might be causing this problem. It's better to use WS_EX_RIGHT | WS_EX_RTLREADING instead of WS_EX_LAYOUTRTL. This will also work with CBN_SELCHANGE.

case CBN_SELENDOK: //(or CBN_SELCHANGE)
    if (SendMessage(hComboBox, CB_GETCURSEL, 0, 0) == 0)
        ModifyStyleEx(hComboBox, WS_EX_RIGHT | WS_EX_RTLREADING, 0);
    else
        ModifyStyleEx(hComboBox, 0, WS_EX_RIGHT | WS_EX_RTLREADING);
    break;
Barmak Shemirani
  • 30,904
  • 6
  • 40
  • 77
  • Thank you, that indeed fixed the issue, at least in the common case of selecting an item with the mouse. There are still occurrences of if, e.g. when using the mouse wheel or the keyboard, but I can live with that. Of course, if you have a solution to this as well, let me know. http://i.imgur.com/Pnz8raX.gif – Paul Aug 21 '16 at 07:59
  • I couldn't duplicate the error with mouse wheel, but the key controls cause annoying display errors as you said. I think the solution is using `WS_EX_RIGHT | WS_EX_RTLREADING` – Barmak Shemirani Aug 22 '16 at 01:55