Jump to content

GUICtrlRichEdit AutoReSize


Oiler
 Share

Recommended Posts

Hello everyone,

First excuse me if there is any typo in this post, because English is not my native language. Before anything i have already search in this forum and google, and i have found one example that's similiar to what I'm trying to solve, but unfortunately it was already what i was using and it's equally inefficient.

I need to use the GUICtrlRichEdit because there is pictures and text in the control (the content varies to much). I know how i can move the control and resize it (ControlMove). What i'm not able to accomplish is to efficiently calculate the size of the control based on the content (or the max size that can get). Usually when the control's content is only text I use GUICtrlLabel and the magic StringSize UDF Melba23, and works like a charm.

Let me show my effort. The first method is to check the maximum size (static in this case) of the content based on the existence of a vertical scroll bar (that`s when it reachs the maximum size), then problems arise, sometimes you need to send a PageDown to control to make sure that there is no bar, another is that the size is not as small as possible.

#include <GUIConstants.au3>
#include <GuiRichEdit.au3>

Global $hGUI = GUICreate("TEST", 900, 800)
Global $hRichEdit = _GUICtrlRichEdit_Create($hGUI, "TEST", 10, 10, 880, 780, BitOR($ES_MULTILINE, $WS_VSCROLL, $ES_AUTOVSCROLL))

GUISetState()

MsgBox(0, "", "Lets find the maximum font size with _GUICtrlRichEdit_ChangeFontSize")

_GUICtrlRichEdit_SetSel($hRichEdit, 0, -1)

For $iFont = 1 To 100
    _GUICtrlRichEdit_ChangeFontSize($hRichEdit, $iFont)
    $aPos = _GUICtrlRichEdit_GetScrollPos($hRichEdit) ; Here is my problem, this is a inefficient method to check if the label has reached its limit.
    If $aPos[1] > 0 Then
        _GUICtrlRichEdit_Undo($hRichEdit)
        ExitLoop
    EndIf
Next

_GUICtrlRichEdit_Deselect($hRichEdit)

MsgBox(0, "", "Maximum size found")

Exit

Second approach is to autosize until the control`s fit the content. It has the same problems the first example.

#include <GUIConstants.au3>
#include <GuiRichEdit.au3>

Global $hGUI = GUICreate("TEST", 1400, 500)
Global $hRichEdit = _GUICtrlRichEdit_Create($hGUI, "TEST", 10, 10, 300, 300, BitOR($ES_MULTILINE, $WS_VSCROLL, $ES_AUTOVSCROLL))
_GUICtrlRichEdit_SetSel($hRichEdit, 0, -1) ; Select all
_GUICtrlRichEdit_ChangeFontSize($hRichEdit, 200) ; Just to make the content bigger then the control
_GUICtrlRichEdit_Deselect($hRichEdit)

GUISetState()

MsgBox(0, "", "The control is to small")

$iHeight = ControlGetPos($hGUI, "", $hRichEdit)[3] ; Get the current height
ControlSend($hGUI, "", $hRichEdit, "{PGDN}")
$aPos = _GUICtrlRichEdit_GetScrollPos($hRichEdit)
If $aPos[1] > 0 Then
    Do
        $aPos = _GUICtrlRichEdit_GetScrollPos($hRichEdit)
        If $aPos[1] = 0 Then
            ControlSend($hGUI, "", $hRichEdit, "{PGDN}") ; Double checks
            $aPos = _GUICtrlRichEdit_GetScrollPos($hRichEdit)
            If $aPos[1] = 0 Then ExitLoop
        EndIf
        $iHeight += 5
        ControlMove($hGUI, "", $hRichEdit, 10, 10, 1380, $iHeight)
    Until $aPos[1] = 0
EndIf

MsgBox(0, "", "Maximum size found")

Exit

Both methods work inefficiently, and it is necessary that the controls are visible which causes the GUI to flicker. That said, I saw a possibility to calculate the control using _GUICtrlRichEdit_SetEventMask($hWnd,  $ENM_REQUESTRESIZE), but I could not apply to the script because of my inexperience and my limited ability to code. From what I understand it is possible to receive the information from EN_REQUESTRESIZE if it is necessary or not to resize and calculate using the REQRESIZE.

Would look like something like this? Or is this the wrong approach?

GUIRegisterMsg($SIZE, "SIZE")
_GUICtrlRichEdit_SetEventMask($hWnd, $ENM_REQUESTRESIZE)

Func SIZE()
    ?
EndFunc

I appreciate any and all help. :)

Link to comment
Share on other sites

You need to do something like this:

 

#include <GUIConstants.au3>
#include <GuiRichEdit.au3>

Global $hGUI = GUICreate("TEST", 900, 800)
Global $hRichEdit = _GUICtrlRichEdit_Create($hGUI, "TEST", 10, 10, 880, 780, BitOR($ES_MULTILINE, $WS_VSCROLL, $ES_AUTOVSCROLL))
_GUICtrlRichEdit_SetEventMask($hRichEdit, $ENM_REQUESTRESIZE)

GUISetState()
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

MsgBox(0, "", "Lets find the maximum font size with _GUICtrlRichEdit_ChangeFontSize")

_GUICtrlRichEdit_SetSel($hRichEdit, 0, -1)

For $iFont = 1 To 100
    _GUICtrlRichEdit_ChangeFontSize($hRichEdit, $iFont)
    $aPos = _GUICtrlRichEdit_GetScrollPos($hRichEdit) ; Here is my problem, this is a inefficient method to check if the label has reached its limit.
    If $aPos[1] > 0 Then
        _GUICtrlRichEdit_Undo($hRichEdit)
        ExitLoop
    EndIf
Next

_GUICtrlRichEdit_Deselect($hRichEdit)

MsgBox(0, "", "Maximum size found")

Exit

Func WM_NOTIFY($hWnd, $iMsg, $iWparam, $iLparam)
    #forceref $iMsg, $iWparam
    Local $hWndFrom, $iCode, $tNMHDR, $tMsgFilter, $hMenu
    $tNMHDR = DllStructCreate($tagNMHDR, $iLparam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hRichEdit
            Switch $iCode
                Case $EN_REQUESTRESIZE
                    ConsoleWrite("Do Something" & @CRLF)
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Saludos

Link to comment
Share on other sites

Hello Danyfirex,

Thanks for the help. :) As I thought you can use the $EN_REQUESTRESIZE to check if the control is to big ou to small, but how i can retrieve REQRESIZE (https://msdn.microsoft.com/pt-br/library/windows/desktop/bb787950(v=vs.85).aspx) so I can use the ControlMove to put the new sizes? Would you do me the kindness to show me how?

Again, thanks for the fast reply.

Link to comment
Share on other sites

mmm I see. Look:

#include <GUIConstants.au3>
#include <GuiRichEdit.au3>
Global Const $tagEQRESIZE=$tagNMHDR & ";" &$tagRECT
Global $hGUI = GUICreate("TEST", 900, 800)
Global $hRichEdit = _GUICtrlRichEdit_Create($hGUI, "TEST", 10, 10, 880, 780, BitOR($ES_MULTILINE, $WS_VSCROLL, $ES_AUTOVSCROLL))
_GUICtrlRichEdit_SetEventMask($hRichEdit, $ENM_REQUESTRESIZE)

GUISetState()
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

MsgBox(0, "", "Lets find the maximum font size with _GUICtrlRichEdit_ChangeFontSize")

_GUICtrlRichEdit_SetSel($hRichEdit, 0, -1)

For $iFont = 1 To 100
    _GUICtrlRichEdit_ChangeFontSize($hRichEdit, $iFont)
    $aPos = _GUICtrlRichEdit_GetScrollPos($hRichEdit) ; Here is my problem, this is a inefficient method to check if the label has reached its limit.
    If $aPos[1] > 0 Then
        _GUICtrlRichEdit_Undo($hRichEdit)
        ExitLoop
    EndIf
Next

_GUICtrlRichEdit_Deselect($hRichEdit)

MsgBox(0, "", "Maximum size found")

Exit

Func WM_NOTIFY($hWnd, $iMsg, $iWparam, $iLparam)
    #forceref $iMsg, $iWparam
    Local $hWndFrom, $iCode, $tNMHDR, $tMsgFilter, $hMenu
    Local $tEQRESIZE=0
    $tNMHDR = DllStructCreate($tagNMHDR, $iLparam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hRichEdit
            Switch $iCode
                Case $EN_REQUESTRESIZE
                    $tEQRESIZE=DllStructCreate($tagEQRESIZE,$iLparam)
                    ConsoleWrite("Size needed: Left: " & $tEQRESIZE.Left & " Top: " & $tEQRESIZE.Top & " ")
                    ConsoleWrite("Right: " & $tEQRESIZE.Right & " Bottom: " & $tEQRESIZE.Bottom & @CRLF)
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Saludos

Link to comment
Share on other sites

Thank you Danyfirex for your time and knowledge, you solved my problem. Now I can make all calculations without the GuiSetState() first, so no more flickering.

Below is an working example if someone is interested.

#include <GUIConstants.au3>
#include <GuiRichEdit.au3>

Global Const $tagEQRESIZE = $tagNMHDR & ";" & $tagRECT
Global $hGUI = GUICreate("TEST", 900, 407)
Global $hRichEdit = _GUICtrlRichEdit_Create($hGUI, "TEST", 10, 10, 880, 5, $ES_MULTILINE)
_GUICtrlRichEdit_SetEventMask($hRichEdit, $ENM_REQUESTRESIZE)

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

MsgBox(0, "", "Lets find the maximum font size with Danyfirex help")

_GUICtrlRichEdit_SetSel($hRichEdit, 0, -1)

For $iFont = 1 To 100
    _GUICtrlRichEdit_ChangeFontSize($hRichEdit, $iFont)
    If ControlGetPos($hGUI, "", $hRichEdit)[3] > 387 Then
        _GUICtrlRichEdit_Undo($hRichEdit)
        ExitLoop
    EndIf
Next

_GUICtrlRichEdit_Deselect($hRichEdit)

GUISetState()

MsgBox(0, "", "Maximum size found")

Exit

Func WM_NOTIFY($hWnd, $iMsg, $iWparam, $iLparam)
    #forceref $iMsg, $iWparam
    Local $hWndFrom, $iCode, $tNMHDR, $tMsgFilter, $hMenu
    Local $tEQRESIZE=0
    $tNMHDR = DllStructCreate($tagNMHDR, $iLparam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hRichEdit
            Switch $iCode
                Case $EN_REQUESTRESIZE
                    $tEQRESIZE = DllStructCreate($tagEQRESIZE, $iLparam)
                    ConsoleWrite("Size needed: Left: " & $tEQRESIZE.Left & " Top: " & $tEQRESIZE.Top & " ")
                    ConsoleWrite("Right: " & $tEQRESIZE.Right & " Bottom: " & $tEQRESIZE.Bottom & @CRLF)
                    ControlMove($hGUI, "", $hRichEdit, 10, 10, 880, $tEQRESIZE.Bottom)
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

For anyone who will play with this i belive that you should read about RECT calc (https://www.autoitscript.com/autoit3/docs/libfunctions/_GUICtrlRichEdit_GetRECT.htm). And some GUI ExStyle messes with this calcs too.

Thanks again Danyfirex for the generosity. :)

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...