RTL Interface: Change some elements to LTR



  • Hello,

    I use NPP in a RTL interface.
    I’d like to change the following elements to LTR:

    1. Text in the Status Bar (i.e. align to left).
    2. Text direction in the Find and Replace various Combo-Boxes.
    3. Text direction in the Incremental Find Bar.

    I’ve managed to change the default text direction in the Incremental Find Bar by calling setDirLTR() when the FindBar is first displayed (in FindIncrementDlg::display(bool toShow) const. (FindReplaceDlg.cpp) ).

    void setDirLTR()
    {
    	INPUT inputDirLTR[4] = { { INPUT_KEYBOARD }, { INPUT_KEYBOARD }, { INPUT_KEYBOARD }, { INPUT_KEYBOARD } };
    
    	inputDirLTR[0].ki.wScan = (WORD)MapVirtualKey(VK_LCONTROL, 0);
    	inputDirLTR[0].ki.wVk = VK_LCONTROL;
    	inputDirLTR[0].ki.dwFlags = 0; // 0 == Key Down.
    
    	inputDirLTR[1].ki.wScan = (WORD)MapVirtualKey(VK_LSHIFT, 0);
    	inputDirLTR[1].ki.wVk = VK_LSHIFT;
    	inputDirLTR[1].ki.dwFlags = 0; // 0 == Key Down.
    
    	inputDirLTR[2].ki.wScan = (WORD)MapVirtualKey(VK_LCONTROL, 0);
    	inputDirLTR[2].ki.wVk = VK_LCONTROL;
    	inputDirLTR[2].ki.dwFlags = KEYEVENTF_KEYUP;
    
    	inputDirLTR[3].ki.wScan = (WORD)MapVirtualKey(VK_LSHIFT, 0);
    	inputDirLTR[3].ki.wVk = VK_LSHIFT;
    	inputDirLTR[3].ki.dwFlags = KEYEVENTF_KEYUP;
    
    	SendInput(4, &inputDirLTR[0], sizeof(INPUT));
    }
    

    Obviously this is a hack.
    I haven’t been able to achieve that with WS_EX_LAYOUTRTL, WS_EX_NOINHERITLAYOUT, WS_EX_LEFT and WS_EX_LTRREADING.

    I’d appreciate your help.

    Best regards.



  • Hello Yaron,

    not sure what you’ve already tested but from MS point of view you have to use 4 steps.

    // Get the window extended style flagsfor the current window.
    DWORD dwStyle = GetWindowExStyle(hwnd_);
    
    // Is the WS_EX_LAYOUTRTL flag present?
    BOOL bWSLayout = dwStyle & WS_EX_LAYOUTRTL;
    
    // Is the WS_EX_RLTREADING flag present?
    BOOL bWSReading = dwStyle & WS_EX_RTLREADING;
    
    // If either the WS_EX_LAYOUTRTL flag or the WS_EX_RLTREADING flag is present,
    // but NOT BOTH, set the reading direction to right to left.
    if ((bWSLayout && !bWSReading) ||  (!bWSLayout && bWSReading))
    {
        pTextFormat_->SetReadingDirection(DWRITE_READING_DIRECTION_RIGHT_TO_LEFT);
    }
    

    Hope this is helpful for you.

    Cheers
    Claudia



  • Hello Claudia,

    Thank you. As always I appreciate your kind help.

    I haven’t tried SetReadingDirection().
    For using it I’d have to add the Dwrite.h header; before doing that I’d like to make sure there isn’t a simpler way.

    With your permission, let’s concentrate on the Status Bar.
    Changing (in StatusBar.cpp)

    return (TRUE == ::SendMessage(_hSelf, SB_SETTEXT, whichPart, (LPARAM)_lastSetText.c_str()));
    

    to

    return (TRUE == ::SendMessage(_hSelf, SB_SETTEXT, whichPart | SBT_POPOUT, (LPARAM)_lastSetText.c_str()));
    

    does change the bar’s style.

    If I understand this article correctly, the text direction can be set there as well.
    What do you think?

    I’d like to align the text to the left.
    The equivalent in your LTR interface would be aligning the the text to the right.

    Best regards.



  • Hello Yaron,

    First of all, I don’t have any experience with LTR/RTL stuff.
    From what I read, yes, it should do the trick but it seems it also depends on the keyboard layout.
    That might be the reason why I can’t get it to work.
    This article I just found indicates this.
    Unfortunattely I can’t test it as I don’t have a dotnet environment ready.

    But from what I understand, creating a window with WS_EX_LAYOUTRTL should be prefered and npp
    uses it already for a couple of windows.

    Cheers
    Claudia



  • Hello Claudia,

    Thanks again. I highly appreciate your time and goodwill.

    But from what I understand, creating a window with WS_EX_LAYOUTRTL should be prefered and npp
    uses it already for a couple of windows.

    Indeed.
    This is how NPP changes the editor text direction:

    void ScintillaEditView::changeTextDirection(bool isRTL)
    {
    	long exStyle = ::GetWindowLongPtr(_hSelf, GWL_EXSTYLE);
    	exStyle = isRTL ? exStyle | WS_EX_LAYOUTRTL : exStyle&(~WS_EX_LAYOUTRTL);
    	::SetWindowLongPtr(_hSelf, GWL_EXSTYLE, exStyle);
    }
    

    I have managed to flip the Status Bar entire layout with WS_EX_LAYOUTRTL etc.; changing only parts of an element seems to be more tricky.

    Best regards.


Log in to reply