orbs

how to send RTL/LTR to RichEdit?

11 posts in this topic

#1 ·  Posted (edited)

my GUI has a RichEdit control, and i want to sent it the RTL and LTR commands by a button in the GUI.

the problem - it has no ControlID (created by the UDF function), and the key combination is Ctrl+Shift which Send() & ControlSend() seems to be unable to handle.

i noticed the example for _GUICtrlEdit_Create(), there mentioned a Windows message called $EN_ALIGN_RTL_EC. i'm trying to send the RichEdit control this message. however, ControlCommand() seems to work only with native controls, but the RichEdit has no ControlID. it does return 1 though, but no effect on the RichEdit control.

any hints are appreciated. this is what i have so far:

#include <GuiRichEdit.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ButtonConstants.au3>

; build GUI
Global Const $nGUI_MaxW = 500, $nGUI_MaxH = 300
Global $nGUI_W = 720, $nGUI_H = 500, $nRichEditOffset = 0, $nRichEditOffsetTop = 30
Global $nToolbarHeight = $nRichEditOffsetTop
Global $hGui = GUICreate('RichEdit RTL/LTR test', $nGUI_W, $nGUI_H, -1, -1, BitOR($WS_MINIMIZEBOX, $WS_MAXIMIZEBOX, $WS_SIZEBOX, $WS_SYSMENU))
; - toolbar ; ** requires and extra lower contour if main rich edit is not docked to edges
Global $gToolbarBackground = GUICtrlCreateLabel('', 0, 0, $nGUI_W, $nToolbarHeight)
GUICtrlSetResizing(-1, BitOR($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKRIGHT, $GUI_DOCKHEIGHT))
GUICtrlSetBkColor(-1, 0xFFFFFF)
GUICtrlSetState(-1, $GUI_DISABLE)
; -- RTL/LRT
Global $bRTL = False
Global $gRTL = GUICtrlCreateCheckbox(ChrW(0xB6) & ChrW(9664), 3, 3, 24, 24, $BS_PUSHLIKE)
GUICtrlSetResizing(-1, BitOR($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE))
GUICtrlSetFont(-1, 10)
; - main
Global $hRichEdit = _GUICtrlRichEdit_Create($hGui, 'line1' & @LF & 'line2' & @LF & 'line3' & @LF & 'line4' & @LF, $nRichEditOffset, $nRichEditOffset + $nRichEditOffsetTop, $nGUI_W - $nRichEditOffset * 2, $nGUI_H - $nRichEditOffset * 2 - $nRichEditOffsetTop - 24, BitOR($ES_MULTILINE, $ES_READONLY, $WS_HSCROLL, $WS_VSCROLL))
_GUICtrlRichEdit_SetSel($hRichEdit, 0, -1, True)
_GUICtrlRichEdit_SetFont($hRichEdit, Default, 'Courier New')
GUISetState()
GUIRegisterMsg($WM_GETMINMAXINFO, "_WM_GETMINMAXINFO")
GUIRegisterMsg($WM_SIZE, "_WM_SIZE")
; work with GUI
Global $iMsg = 0
While True
    $iMsg = GUIGetMsg()
    Switch $iMsg
        Case $GUI_EVENT_CLOSE
            _GUICtrlRichEdit_Destroy($hRichEdit)
            Exit
        Case $gRTL
            $bRTL = Not $bRTL
            If $bRTL Then
                _GUICtrlRichEdit_SetSel($hRichEdit, 0, -1, True)
                ConsoleWrite(ControlSend($hGui, '', $hRichEdit, 'SendCommandID', $EN_ALIGN_RTL_EC) & @LF)
            Else
                _GUICtrlRichEdit_SetSel($hRichEdit, 0, -1, True)
                ConsoleWrite(ControlSend($hGui, '', $hRichEdit, 'SendCommandID', $EN_ALIGN_LTR_EC) & @LF)
            EndIf
    EndSwitch
WEnd

#region resizing funcs
Func _WM_GETMINMAXINFO($hWnd, $iMsg, $wParam, $lParam)
    If $hWnd = $hGui Then
        $tagMaxinfo = DllStructCreate("int;int;int;int;int;int;int;int;int;int", $lParam)
        DllStructSetData($tagMaxinfo, 7, $nGUI_MaxW) ; min X
        DllStructSetData($tagMaxinfo, 8, $nGUI_MaxH) ; min Y
        Return 0
    EndIf
EndFunc   ;==>_WM_GETMINMAXINFO

Func _WM_SIZE($hWnd, $iMsg, $wParam, $lParam)
    ; ref: http://www.autoitscript.com/forum/topic/123904-solved-auto-resizing-richedit-control/#entry860464
    If $hWnd = $hGui Then
        Local $iWidth = _WinAPI_LoWord($lParam) ; the entire GUI internal width
        Local $iHeight = _WinAPI_HiWord($lParam) ; the entire GUI internal height
        _WinAPI_MoveWindow($hRichEdit, $nRichEditOffset, $nRichEditOffset + $nRichEditOffsetTop, $iWidth - $nRichEditOffset * 2, $iHeight - $nRichEditOffset * 2 - $nRichEditOffsetTop)
    EndIf
EndFunc   ;==>_WM_SIZE
#endregion resizing funcs
Edited by orbs

Share this post


Link to post
Share on other sites



orbs,

This works for me: :)

; Add these includes
#include <Constants.au3>
#include <WinAPI.au3>

; And then the checkbox case looks like this
Case $gRTL
    If GUICtrlRead($gRTL) = 1 Then
        ; RTL
        _WinAPI_SetWindowLong($hRichEdit, $GWL_EXSTYLE, $WS_EX_LAYOUTRTL)
    Else
        ; Normal
        _WinAPI_SetWindowLong($hRichEdit, $GWL_EXSTYLE, 0)
    EndIf
Is that what you want? :)

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

thanks Melba23, i was not aware i can change an individual control style to RTL (i was under the impression it applies to the entire GUI only).

one issue: this technique as-is makes the border of the RichEdit to disappear. i had to modify it as such to add the style $WS_EX_CLIENTEDGE:

; switch to RTL: changed from this:
_WinAPI_SetWindowLong($hRichEdit, $GWL_EXSTYLE, $WS_EX_LAYOUTRTL)
; to this:
_WinAPI_SetWindowLong($hRichEdit, $GWL_EXSTYLE, BitOR($WS_EX_LAYOUTRTL,$WS_EX_CLIENTEDGE))

; switch back to LTR: changed from this:
_WinAPI_SetWindowLong($hRichEdit, $GWL_EXSTYLE, 0)
; to this:
_WinAPI_SetWindowLong($hRichEdit, $GWL_EXSTYLE, $WS_EX_CLIENTEDGE)

i chose $WS_EX_CLIENTEDGE because it looks to me as the default extended style for RichEdit. i sought to apply the default extended RichEdit style in conjunction with the RTL style, but the help for _GUICtrlRichEdit_Create() does not specify the default extended style, which is (obviously?) not 0.

am i missing something important here?

this is the modified example (after my fix) - to demonstrate the issue, it employs an offset from the edges of the GUI, and a background color.

#include <GuiRichEdit.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ButtonConstants.au3>
; Add these includes for RTL. ref: http://www.autoitscript.com/forum/topic/167233-how-to-send-rtlltr-to-richedit/
#include <Constants.au3>
#include <WinAPI.au3>

; build GUI
Global Const $nGUI_MaxW = 500, $nGUI_MaxH = 300
Global $nGUI_W = 720, $nGUI_H = 500, $nRichEditOffset = 10, $nRichEditOffsetTop = 30
Global $nToolbarHeight = $nRichEditOffsetTop
Global $hGui = GUICreate('RichEdit RTL/LTR test', $nGUI_W, $nGUI_H, -1, -1, BitOR($WS_MINIMIZEBOX, $WS_MAXIMIZEBOX, $WS_SIZEBOX, $WS_SYSMENU))
GUISetBkColor(0xCCDDEE)
; - toolbar ; ** requires and extra lower contour if main rich edit is not docked to edges
Global $gToolbarBackground = GUICtrlCreateLabel('', 0, 0, $nGUI_W, $nToolbarHeight)
GUICtrlSetResizing(-1, BitOR($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKRIGHT, $GUI_DOCKHEIGHT))
GUICtrlSetBkColor(-1, 0xFFFFFF)
GUICtrlSetState(-1, $GUI_DISABLE)
; -- RTL/LRT
Global $bRTL = False
Global $gRTL = GUICtrlCreateCheckbox(ChrW(0xB6) & ChrW(9664), 3, 3, 24, 24, $BS_PUSHLIKE)
GUICtrlSetResizing(-1, BitOR($GUI_DOCKTOP, $GUI_DOCKLEFT, $GUI_DOCKSIZE))
GUICtrlSetFont(-1, 10)
; - main
Global $hRichEdit = _GUICtrlRichEdit_Create($hGui, 'line1' & @LF & 'line2' & @LF & 'line3' & @LF & 'line4' & @LF, $nRichEditOffset, $nRichEditOffset + $nRichEditOffsetTop, $nGUI_W - $nRichEditOffset * 2, $nGUI_H - $nRichEditOffset * 2 - $nRichEditOffsetTop - 24, BitOR($ES_MULTILINE, $ES_READONLY, $WS_HSCROLL, $WS_VSCROLL))
_GUICtrlRichEdit_SetSel($hRichEdit, 0, -1, True)
_GUICtrlRichEdit_SetFont($hRichEdit, Default, 'Courier New')
GUISetState()
GUIRegisterMsg($WM_GETMINMAXINFO, "_WM_GETMINMAXINFO")
GUIRegisterMsg($WM_SIZE, "_WM_SIZE")
; work with GUI
Global $iMsg = 0
While True
    $iMsg = GUIGetMsg()
    Switch $iMsg
        Case $GUI_EVENT_CLOSE
            _GUICtrlRichEdit_Destroy($hRichEdit)
            Exit
        Case $gRTL
            $bRTL = Not $bRTL
            If $bRTL Then
                _WinAPI_SetWindowLong($hRichEdit, $GWL_EXSTYLE, BitOR($WS_EX_LAYOUTRTL,$WS_EX_CLIENTEDGE))
            Else
                _WinAPI_SetWindowLong($hRichEdit, $GWL_EXSTYLE, $WS_EX_CLIENTEDGE)
            EndIf
    EndSwitch
WEnd

#region resizing funcs
Func _WM_GETMINMAXINFO($hWnd, $iMsg, $wParam, $lParam)
    If $hWnd = $hGui Then
        $tagMaxinfo = DllStructCreate("int;int;int;int;int;int;int;int;int;int", $lParam)
        DllStructSetData($tagMaxinfo, 7, $nGUI_MaxW) ; min X
        DllStructSetData($tagMaxinfo, 8, $nGUI_MaxH) ; min Y
        Return 0
    EndIf
EndFunc   ;==>_WM_GETMINMAXINFO

Func _WM_SIZE($hWnd, $iMsg, $wParam, $lParam)
    ; ref: http://www.autoitscript.com/forum/topic/123904-solved-auto-resizing-richedit-control/#entry860464
    If $hWnd = $hGui Then
        Local $iWidth = _WinAPI_LoWord($lParam) ; the entire GUI internal width
        Local $iHeight = _WinAPI_HiWord($lParam) ; the entire GUI internal height
        _WinAPI_MoveWindow($hRichEdit, $nRichEditOffset, $nRichEditOffset + $nRichEditOffsetTop, $iWidth - $nRichEditOffset * 2, $iHeight - $nRichEditOffset * 2 - $nRichEditOffsetTop)
    EndIf
EndFunc   ;==>_WM_SIZE
#endregion resizing funcs

Share this post


Link to post
Share on other sites

orbs,

 

am i missing something important here?

Unlike the native AutoIt controls, the UDF-created controls have no default styles applied - you have to define absolutely everything yourself. Hence the need to use the $WS_EX_CLIENTEDGE style when ever you change. Using 0 just means no style, which I suppose is the default for UDF controls but not in the sense you understood it. ;)

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

you have to define absolutely everything yourself 

 

 

i didn't need to define any extended style when i created the RichEdit control now, did i? so there must be some kind of default extended style applied...?

one might think the border is defined by the normal style, not the extended style, but then it shouldn't have been affected by the changing of the extended style.

Share this post


Link to post
Share on other sites

orbs,

Having looked inside the _GUICtrlRichEdit_Create function I see the following:

If $iStyle = -1 Then $iStyle = BitOR($ES_WANTRETURN, $ES_MULTILINE)

If BitAND($iStyle, $ES_MULTILINE) <> 0 Then $iStyle = BitOR($iStyle, $ES_WANTRETURN)
If $iExStyle = -1 Then $iExStyle = 0x200 ;  $DS_FOREGROUND
So you are right, there is indeed a default style and extended style set - mea culpa. ;)

And if you want to see how to add/remove a style from an existing set, the Setting Styles tutorial in the Wiki explains with an example. :)

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

me no think. me should have looked inside UDF. me go bang head against nearest wall now.

 

meanwhile, it seems this technique is not quite perfect. it makes a mess when numbers and characters like comma, quote and double-quotes are within the text in the RTL language. for example,

Line1
Line2
Line3 

becomes in RTL:

1Line
2Line
3Line

when switching manually (keyboard combination Ctrl+Shift), there is no problem.

i stumbled upon this topic: '?do=embed' frameborder='0' data-embedContent>>

the solution suggests applying the style $ES_RIGHT to the control (normal style, not extended style). i tried this:

_WinAPI_SetWindowLong($hRichEdit, $GWL_STYLE, BitOR($iDefaultStyle, $ES_RIGHT))

after declaring the default style, of course, and using it to create the RichEdit:

Global $iDefaultStyle=BitOR($ES_MULTILINE, $ES_READONLY, $WS_HSCROLL, $WS_VSCROLL)

but that does not seem to change anything. i must be misunderstanding the entire thing. any suggestion?

Share this post


Link to post
Share on other sites

orbs,

Sorry, no. :(

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

i added a button that i can click and will show me a summary of the control styles at any given time, using _WinAPI_GetWindowLong($hRichEdit, $GWL_EXSTYLE)

the normal style does not change. the extended style changes from 512 to 4194816 when RTL, and back to 512 when LTR. fine. now, how does it change if i manually switch to RTL (by Ctrl+Shift, which works well)?

it doesn't. the style does not change. something else changes.

AutoIt Window Info tool detects no change in the properties of the control after i hit Ctrl+Shift.

perhaps there is a way to "trap" the operation that happens to the control?

Share this post


Link to post
Share on other sites

i used Spy++ to try to trap window messages that happens when i hit Ctrl+Shift.

it detected only the key press (first 4 lines for Ctrl+Shift to RTL, next 4 lines revert).

<000001> 000205E6 P WM_KEYDOWN nVirtKey:VK_CONTROL cRepeat:1 ScanCode:1D fExtended:1 fAltDown:0 fRepeat:0 fUp:0
<000002> 000205E6 P WM_KEYDOWN nVirtKey:VK_SHIFT cRepeat:1 ScanCode:36 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<000003> 000205E6 P WM_KEYUP nVirtKey:VK_SHIFT cRepeat:1 ScanCode:36 fExtended:0 fAltDown:0 fRepeat:1 fUp:1
<000004> 000205E6 P WM_KEYUP nVirtKey:VK_CONTROL cRepeat:1 ScanCode:1D fExtended:1 fAltDown:0 fRepeat:1 fUp:1
<000005> 000205E6 P WM_KEYDOWN nVirtKey:VK_CONTROL cRepeat:1 ScanCode:1D fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<000006> 000205E6 P WM_KEYDOWN nVirtKey:VK_SHIFT cRepeat:1 ScanCode:2A fExtended:0 fAltDown:0 fRepeat:0 fUp:0
<000007> 000205E6 P WM_KEYUP nVirtKey:VK_SHIFT cRepeat:1 ScanCode:2A fExtended:0 fAltDown:0 fRepeat:1 fUp:1
<000008> 000205E6 P WM_KEYUP nVirtKey:VK_CONTROL cRepeat:1 ScanCode:1D fExtended:0 fAltDown:0 fRepeat:1 fUp:1

with no other options, i'm willing to take a shot at simulating these keystrokes. what can i use from this output that will help me doing it? how do i call this WM_KEYDOWN and WM_KEYUP? what are nVirtKey, ScanCode?

Share this post


Link to post
Share on other sites

it seems simulating key press is rather unstable, and the key combination varies between users. i will not pursue this method. for now i give up.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now