Jump to content

Keeping 2 controls the same height after resizing


ahha
 Share

Recommended Posts

I'm trying to have a left side edit control display line numbers (line numbers control) for a right side edit control (edit control).
The issue is when resizing the edit control having the line numbers control resize properly in height.  (NOT a keeping the controls in sync Q.)
Hold down the left mouse button and resize vertically and horizontally and you'll see the effect (the line number control height changes differently than the edit control).
Then when you release the mouse button the program does the resizing.
I thought setting the GUICtrlSetResizing would do it, but it does not.
I've had to resort to checking the edit control height and then using ControlMove to adjust the line numbers control height (_ResizeLN()) in the While 1 loop.
I've tried putting the _ResizeLN() in the Func WM_SIZE but it does not seem to be working properly (plus I probably am doing something dumb).

My questions are:
Q1) Is there a way to get the line numbers control to height resize just like the edit control using GUICtrlSetResizing?
Q2) If not Q1) then is there a way using Func WM_SIZE?

The reason I ask is because I hate to check every time in the While 1 loop for a possible height adjustment of the line numbers control.

#AutoIt3Wrapper_run_debug_mode=Y    ;use this to debug in console window <--- LOOK  ;
Opt("MustDeclareVars", 1) ;0=no, 1=require pre-declaration
;v3ai - trying to add line numbers on left

#include <Debug.au3>            ;for _DebugArrayDisplay
#include <GUIConstantsEx.au3>
#include <GUIEdit.au3>
#include <GuiStatusBar.au3>     ;for status bar
#include <WindowsConstants.au3>

Global $g_hGUI, $g_hStatus
Global $g_iOldLineNum = 0, $g_iLineNum = 1  ;init values

Global $g_hEdit, $g_aPos_hEdit
Global $g_hLNEdit, $g_aPos_hLNEdit

Global $iBorderWidth = 4

_SetUpWindows() ;set up GUI, Edit, and StatusBar    ;has GUISetState(@SW_SHOW, $g_hGUI)

_MAINLoop() ;main loop

Exit


Func _SetUpWindows()
    $g_hGUI = GUICreate("My GUI", 800, 570, -1, -1, BitOR($WS_MAXIMIZEBOX, $WS_MINIMIZEBOX, $WS_SIZEBOX), BitOR($WS_EX_CLIENTEDGE, $WS_EX_ACCEPTFILES))     ;handle
    GUISetBkColor(0x00f000, $g_hGUI)        ;window background green 0x00f000 so see individual controls

    ;--- Create status bar and Set parts
    Local $aParts[3] = [150, 300, -1]   ;right edge of 1st part at 75, 2nd at 150, 3rd = -1 meaning right edge extends to the border of the window  ;v2gq need more room for Line: xxxxxx / yyyyyy
    $g_hStatus = _GUICtrlStatusBar_Create($g_hGUI)
    _GUICtrlStatusBar_SetParts($g_hStatus, $aParts)
    _GUICtrlStatusBar_SetText($g_hStatus, "Line: xx", 0)    ;& _GUICtrlEdit_LineFromChar($g_hEdit, -1) + 1)     ;+1 as Zero based
    _GUICtrlStatusBar_SetText($g_hStatus, "Part 2", 1)      ;"Part 2", 1)
    _GUICtrlStatusBar_SetText($g_hStatus, "Part 3", 2)      ;"Part 3", 2)

    ;--- Create Edit Control in rest of window area
    Local $aClientSize = WinGetClientSize($g_hGUI)  ;[0] = Width of window's client area    ;[1] = Height of window's client area

    Local $iStatusBarHeight = _GUICtrlStatusBar_GetHeight($g_hStatus)   ;get actual height in case changed above
    ;Pause("$iStatusBarHeight = '" & $iStatusBarHeight & "'")   ;we get 17 which is not correct - need to account for border on status bar also
    $iStatusBarHeight = $iStatusBarHeight +1    ;<-- border touches     +2  ;<-- leaves a border 1 pixel
    Local $iMFF = 5 ;manual fudge factor
    Local $iWE = $aClientSize[0]-(2*$iBorderWidth)  ;Width of Edit
    Local $iHE = ($aClientSize[1]-(2*$iBorderWidth)) - $iStatusBarHeight - $iMFF    ;Height of Edit ;Manual Fudge Factor

    $g_hEdit = GUICtrlCreateEdit("", $iBorderWidth + 100, $iBorderWidth, $iWE - 100, $iHE, BitOR($ES_AUTOVSCROLL, $ES_WANTRETURN, $WS_VSCROLL, $WS_HSCROLL, $ES_NOHIDESEL)) ;control ID

    GUICtrlSetResizing($g_hEdit, $GUI_DOCKBORDERS)  ;control will grow as the window
    GUICtrlSetBkColor($g_hEdit,0xFFFFFF)    ;0xFCD299   ;0xB9700A   ;0xFDB44E   ;0xffa500)
    GUICtrlSetColor($g_hEdit,0x000000)  ;text color
    GUICtrlSetFont($g_hEdit, 10, 400, 0, "Courier New")     ;monospace font
    _GUICtrlEdit_SetLimitText($g_hEdit, -1)

    ;now Set parts in status bar
    Local $sMsg = "Line: " & (_GUICtrlEdit_LineFromChar($g_hEdit, -1) + 1) & " / " & _GUICtrlEdit_GetLineCount($g_hEdit)    ;+1 as Zero based
    _GUICtrlStatusBar_SetText($g_hStatus, $sMsg, 0)     ;+1 as Zero based   ;Part 0 to show Line:

    ;looks like I need to dynamically scale the height on resizing? - do in While 1 loop
    Global $g_hLNEdit = GUICtrlCreateEdit("1234567", $iBorderWidth, $iBorderWidth, 70, $iHE, BitOR($ES_AUTOVSCROLL, $ES_WANTRETURN))    ;control ID ;works

    GUICtrlSetResizing($g_hLNEdit, BitOR($GUI_DOCKLEFT, $GUI_DOCKTOP, $GUI_DOCKWIDTH))
    GUICtrlSetBkColor($g_hLNEdit,0xFCD299)
    GUICtrlSetColor($g_hLNEdit,0x0000ff)    ;text color
    GUICtrlSetFont($g_hLNEdit, 10, 400, 0, "Courier New")       ;change default font
    _GUICtrlEdit_SetLimitText($g_hLNEdit, -1)

    Local $i, $sMsg = "", $sI
    For $i = 1 To 2345  ;build up a string for testing
        $sI = StringRight("        " & $i, 7)
        $sMsg = $sMsg & $sI&@CRLF   ;need right justified, since monospace prefix with spaces " "
    Next
    _GUICtrlEdit_SetText($g_hLNEdit, $sMsg) ;display

    GUISetState(@SW_SHOW, $g_hGUI)      ;--- Let's show our creation

    GUIRegisterMsg($WM_SIZE, "WM_SIZE")

EndFunc     ;Func _SetUpWindows()


Func WM_SIZE($hWnd, $iMsg, $wParam, $lParam)    ;Resize the status bar when GUI size changes
    ;_ResizeLN()        ;resize $g_hLNEdit based on $g_hEdit    ;does not always fully adjust so keep in While1 loop
    _GUICtrlStatusBar_Resize($g_hStatus)
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_SIZE

Func  _ResizeLN()
    ;Local $dHRatio ;decimal Height ratio
    Local $aPos_hEdit = ControlGetPos("", "", $g_hEdit)     ;$a[0] = X position, $a[1] = Y position, $a[2] = Width, $a[3] = Height
    ;_DebugArrayDisplay($aPos_hEdit, "$aPos_hEdit")
    Local $aPos_hLNEdit = ControlGetPos("", "", $g_hLNEdit)
    ;_DebugArrayDisplay($aPos_hLNEdit, "$aPos_hLNEdit")
    ;$dHRatio = $aPos_hEdit[3] / $aPos_hLNEdit[3]
    ;Pause("$dHRatio = '" & $dHRatio & "'")
    ;this is all very interesting but we want them the same height so redraw $g_hLNEdit if needed
    if $aPos_hLNEdit[3] <> $aPos_hEdit[3] Then  ;redraw/move
        ;recall     Global $g_hLNEdit = GUICtrlCreateEdit("1234567", $iBorderWidth, $iBorderWidth, 70, $iHE, BitOR($ES_AUTOVSCROLL, $ES_WANTRETURN))    ;control ID ;works
        ;GUICtrlCreateEdit ( "text", left, top [, width [, height [, style = -1 [, exStyle = -1]]]] )

        ;show what we're doing
        Local $sStatus =    "Edit Window height = '" & $aPos_hEdit[3] & "'" & @CRLF & _
                            "Line Window height = '" & $aPos_hLNEdit[3] & "'" & @CRLF
        ControlSetText("", "", $g_hEdit, $sStatus ) ;show status - use handle to directly address it
;~      Pause("Click to adjust.")

        ;GUICtrlSetPos($aPos_hLNEdit, $iBorderWidth, $iBorderWidth, 70, $aPos_hEdit[3])     ;does not seems to resize vertically
        ControlMove("", "", $g_hLNEdit, Default, Default, 70, $aPos_hEdit[3])   ;WORKS!
    EndIf
EndFunc         ;Func  _ResizeLN()


Func _MAINLoop()
    Local $nMsg, $aMsg, $iReturn, $sMsg

    ;MAIN loop START
    While 1 ;Do everything inside this loop while the program is running.
        $aMsg = GUIGetMsg(1)    ;Check what's happening in the GUI
        $nMsg = $aMsg[0]        ;now I know that there is just 1 GUI so I can just use [0]
        ;skip checking if no event
        If $nMsg <> 0 Then  ;we have a message so
            Switch $nMsg    ;Check for GUI events
                Case $GUI_EVENT_CLOSE
                    Exit    ;program
                Case Else
                    ;Pause("$nMsg = '" & $nMsg & "'")
                    ;do nothing as some negative values used for other purposes
            EndSwitch   ;End running through GUI events.
        EndIf

        ;---- do these always ----
        ;Sleep(20)  ;Not really needed since GUIGetMsg() has a built-in delay.

        ;possibly update Line:
        $g_iLineNum = _GUICtrlEdit_LineFromChar($g_hEdit, -1)   ;get current line, Zero based
        If $g_iOldLineNum <> $g_iLineNum Then   ;it's changed
            $g_iOldLineNum = $g_iLineNum    ;so update
            $sMsg = "Line: " & $g_iLineNum + 1 & " / " & _GUICtrlEdit_GetLineCount($g_hEdit)    ;+1 as Zero based
            _GUICtrlStatusBar_SetText($g_hStatus, $sMsg, 0)     ;Part 0 to show Line:
        EndIf

        ;check to see if resizing occurred for possible dynamic adjustment of Line Number Edit box
        ;probably need to learn to do this in Func WM_SIZE
        _ResizeLN()

    WEnd    ;End main body loop
    ;MAIN loop END

EndFunc     ;Func _MAINLoop()


Func  Pause($text="")
    ;__scrolltext("Debug: Paused " & $text & @CRLF)
    MsgBox(262144, "DEBUG", "Paused: " & $text)
EndFunc     ;Func  Pause($text="")

 

Link to comment
Share on other sites

@argumentum Interesting.  I hacked the example you point to to make the 2 edit heights the same and sure enough they track the height of each other when resizing the GUI.  I then took the GUICreate options you used and plugged them into the above code.
It still has the same issue.  I then decided to set the line number and edit control using the same parameters for creation.  Still the same height adjustment issue.  Thanks for your input.  I'll keep looking for an answer.

Link to comment
Share on other sites

maybe you can use the same control ISN Studio uses. It's SciTE 's DLL (Scintilla.dll). For what I see ( just now run your example ), you'd like to make an editor of sorts, and in ISN studio you get the source to get the chunks of code, to know how to use the editor/Scite in your project. It'd surely be simpler than what Win32 controls were design for, in trying to do what your GUI shows you'd like to have. 

Edited by argumentum

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

You are correct it's an editor of sorts.  Thanks for the intro to ISN Studio.  It looks impressive.
I've updated the code to show how I sync the line numbers as an FYI for others.  I'm unsure how to replace the code in the initial listing, so it's listed here.

#AutoIt3Wrapper_run_debug_mode=Y    ;use this to debug in console window <--- LOOK  ;
Opt("MustDeclareVars", 1) ;0=no, 1=require pre-declaration
;v3ai - trying to add line numbers on left
;v3aj - keep line number control synced with right edit control line number
;v3ak - cleaned up some code

#include <Debug.au3>            ;for _DebugArrayDisplay
#include <GUIConstantsEx.au3>
#include <GUIEdit.au3>
#include <GuiStatusBar.au3>     ;for status bar
#include <WindowsConstants.au3>

Global $g_hGUI, $g_hStatus
Global $g_iOldLineNum = 0, $g_iLineNum = 1  ;init values

Global $g_ihEditFVLineOld = 0   ;0 based first visible line in $g_hEdit control

Global $g_hEdit, $g_aPos_hEdit
Global $g_hLNEdit, $g_aPos_hLNEdit

Global $iBorderWidth = 4

_SetUpWindows() ;set up GUI, Edit, and StatusBar    ;has GUISetState(@SW_SHOW, $g_hGUI)

_MAINLoop() ;main loop

Exit


Func _SetUpWindows()
    $g_hGUI = GUICreate("My GUI", 800, 570, -1, -1, BitOR($WS_MAXIMIZEBOX, $WS_MINIMIZEBOX, $WS_SIZEBOX), BitOR($WS_EX_CLIENTEDGE, $WS_EX_ACCEPTFILES))     ;handle
    GUISetBkColor(0x00f000, $g_hGUI)        ;window background green 0x00f000 so see individual controls

    ;--- Create status bar and Set parts
    Local $aParts[3] = [150, 300, -1]   ;right edge of 1st part at 75, 2nd at 150, 3rd = -1 meaning right edge extends to the border of the window  ;v2gq need more room for Line: xxxxxx / yyyyyy
    $g_hStatus = _GUICtrlStatusBar_Create($g_hGUI)
    _GUICtrlStatusBar_SetParts($g_hStatus, $aParts)
    _GUICtrlStatusBar_SetText($g_hStatus, "Line: xx", 0)    ;& _GUICtrlEdit_LineFromChar($g_hEdit, -1) + 1)     ;+1 as Zero based
    _GUICtrlStatusBar_SetText($g_hStatus, "Part 2", 1)      ;"Part 2", 1)
    _GUICtrlStatusBar_SetText($g_hStatus, "Part 3", 2)      ;"Part 3", 2)

    ;--- Create Edit Control in rest of window area
    Local $aClientSize = WinGetClientSize($g_hGUI)  ;[0] = Width of window's client area    ;[1] = Height of window's client area

    Local $iStatusBarHeight = _GUICtrlStatusBar_GetHeight($g_hStatus)   ;get actual height in case changed above
    ;Pause("$iStatusBarHeight = '" & $iStatusBarHeight & "'")   ;we get 17 which is not correct - need to account for border on status bar also
    $iStatusBarHeight = $iStatusBarHeight +1    ;<-- border touches     +2  ;<-- leaves a border 1 pixel
    Local $iMFF = 5 ;manual fudge factor
    Local $iWE = $aClientSize[0]-(2*$iBorderWidth)  ;Width of Edit
    Local $iHE = ($aClientSize[1]-(2*$iBorderWidth)) - $iStatusBarHeight - $iMFF    ;Height of Edit ;Manual Fudge Factor

    $g_hEdit = GUICtrlCreateEdit("", $iBorderWidth + 100, $iBorderWidth, $iWE - 100, $iHE, BitOR($ES_AUTOVSCROLL, $ES_WANTRETURN, $WS_VSCROLL, $WS_HSCROLL, $ES_NOHIDESEL)) ;control ID

    GUICtrlSetResizing($g_hEdit, $GUI_DOCKBORDERS)  ;control will grow as the window
    GUICtrlSetBkColor($g_hEdit,0xFFFFFF)    ;0xFCD299   ;0xB9700A   ;0xFDB44E   ;0xffa500)
    GUICtrlSetColor($g_hEdit,0x000000)  ;text color
    GUICtrlSetFont($g_hEdit, 10, 400, 0, "Courier New")     ;monospace font
    _GUICtrlEdit_SetLimitText($g_hEdit, -1)

    ;now Set parts in status bar
    Local $sMsg = "Line: " & (_GUICtrlEdit_LineFromChar($g_hEdit, -1) + 1) & " / " & _GUICtrlEdit_GetLineCount($g_hEdit)    ;+1 as Zero based
    _GUICtrlStatusBar_SetText($g_hStatus, $sMsg, 0)     ;+1 as Zero based   ;Part 0 to show Line:

    ;looks like I need to dynamically scale the height on resizing? - do in While 1 loop
    Global $g_hLNEdit = GUICtrlCreateEdit("1234567", $iBorderWidth, $iBorderWidth, 70, $iHE, BitOR($ES_AUTOVSCROLL, $ES_WANTRETURN))    ;control ID ;works

    GUICtrlSetResizing($g_hLNEdit, BitOR($GUI_DOCKLEFT, $GUI_DOCKTOP, $GUI_DOCKWIDTH))
    GUICtrlSetBkColor($g_hLNEdit,0xFCD299)
    GUICtrlSetColor($g_hLNEdit,0x0000ff)    ;text color
    GUICtrlSetFont($g_hLNEdit, 10, 400, 0, "Courier New")       ;change default font
    _GUICtrlEdit_SetLimitText($g_hLNEdit, -1)

    Local $i, $sMsg = "", $sI
    For $i = 1 To 2345  ;build up a string for testing
        $sI = StringRight("        " & $i, 7)
        $sMsg = $sMsg & $sI&@CRLF   ;need right justified, since monospace prefix with spaces " "
    Next
    _GUICtrlEdit_SetText($g_hLNEdit, $sMsg) ;display

    GUISetState(@SW_SHOW, $g_hGUI)      ;--- Let's show our creation

    GUIRegisterMsg($WM_SIZE, "WM_SIZE")
EndFunc     ;Func _SetUpWindows()


Func WM_SIZE($hWnd, $iMsg, $wParam, $lParam)    ;Resize the status bar when GUI size changes
    ;_ResizeLN()        ;resize $g_hLNEdit based on $g_hEdit    ;does not always fully adjust so keep in While 1 loop
    ;_SyncLN()          ;keep these user funcs out of this Func WM_SIZE see: https://www.autoitscript.com/forum/topic/107977-gui_rundefmsg-and-fdblclk/#comment-761384
    _GUICtrlStatusBar_Resize($g_hStatus)
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_SIZE

Func  _ResizeLN()
    ;Local $dHRatio ;decimal Height ratio
    Local $aPos_hEdit = ControlGetPos($g_hGUI, "", $g_hEdit)        ;$a[0] = X position, $a[1] = Y position, $a[2] = Width, $a[3] = Height
    ;_DebugArrayDisplay($aPos_hEdit, "$aPos_hEdit")
    Local $aPos_hLNEdit = ControlGetPos($g_hGUI, "", $g_hLNEdit)
    ;_DebugArrayDisplay($aPos_hLNEdit, "$aPos_hLNEdit")
    ;$dHRatio = $aPos_hEdit[3] / $aPos_hLNEdit[3]
    ;Pause("$dHRatio = '" & $dHRatio & "'")
    ;this is all very interesting but we want them the same height so redraw $g_hLNEdit if needed
    If $aPos_hLNEdit[3] <> $aPos_hEdit[3] Then  ;redraw/move
        ;recall     Global $g_hLNEdit = GUICtrlCreateEdit("1234567", $iBorderWidth, $iBorderWidth, 70, $iHE, BitOR($ES_AUTOVSCROLL, $ES_WANTRETURN))    ;control ID ;works
        ;GUICtrlCreateEdit ( "text", left, top [, width [, height [, style = -1 [, exStyle = -1]]]] )

        ;show what we're doing
;~      Local $sStatus =    "Edit Window height = '" & $aPos_hEdit[3] & "'" & @CRLF & _
;~                          "Line Window height = '" & $aPos_hLNEdit[3] & "'" & @CRLF
;~      ControlSetText("My GUI", "", $g_hEdit, $sStatus )   ;show status - use handle to directly address it
;~      Pause("Click to adjust.")

        ;GUICtrlSetPos($aPos_hLNEdit, $iBorderWidth, $iBorderWidth, 70, $aPos_hEdit[3])     ;does not seems to resize vertically
        ControlMove("", "", $g_hLNEdit, Default, Default, 70, $aPos_hEdit[3])   ;WORKS!
    EndIf
EndFunc         ;Func  _ResizeLN()


Func  _SyncLN()
    ;A note about _GUICtrlEdit_GetFirstVisibleLine - it keeps track from the very first line (which is 0) what is displayed
    ;for our purposes we don't want to create a line number control having a huge set of numbers like from 1 to a million or plus
    ;what we want to do is simply show what the edit box line number is so we can dyamically create the line numbers
    ;and only change the line numbers when the $g_hEdit first visible line changes
    ;recall initially Global $g_ihEditFVLineOld = 0 ;0 based first visible line in $g_hEdit control

    Local $i_hEditFVLine = _GUICtrlEdit_GetFirstVisibleLine($g_hEdit)       ;0 based first visible line in $g_hEdit control

    If $g_ihEditFVLineOld <> $i_hEditFVLine Then    ;put new LN ;-1 as line numbers start with 1 and _GUICtrlEdit_GetFirstVisibleLine is 0 based
        ;need to fill $g_hLNEdit with line numbers and since starting at the top it's unlikely to be more than 100 lines
        Local $i, $sMsg = "", $sI
        For $i = $i_hEditFVLine + 1 To $i_hEditFVLine + 100 ;build up a string for testing
            $sI = StringRight("        " & $i, 7)
            $sMsg = $sMsg & $sI&@CRLF   ;need right justified, since monospace prefix with spaces " "
        Next
        _GUICtrlEdit_SetText($g_hLNEdit, $sMsg) ;display
        $g_ihEditFVLineOld = $i_hEditFVLine     ;update the old first view
    EndIf
EndFunc


Func _MAINLoop()
    Local $nMsg, $aMsg, $iReturn, $sMsg

    ;MAIN loop START
    While 1 ;Do everything inside this loop while the program is running.
        $aMsg = GUIGetMsg(1)    ;Check what's happening in the GUI
        $nMsg = $aMsg[0]        ;now I know that there is just 1 GUI so I can just use [0]
        ;skip checking if no event
        If $nMsg <> 0 Then  ;we have a message so
            Switch $nMsg    ;Check for GUI events
                Case $GUI_EVENT_CLOSE
                    Exit    ;program
                Case Else
                    ;Pause("$nMsg = '" & $nMsg & "'")
                    ;do nothing as some negative values used for other purposes
            EndSwitch   ;End running through GUI events.
        EndIf

        ;---- do these always ----
        ;Sleep(20)  ;Not really needed since GUIGetMsg() has a built-in delay.

        ;possibly update Line:
        $g_iLineNum = _GUICtrlEdit_LineFromChar($g_hEdit, -1)   ;get current line, Zero based
        If $g_iOldLineNum <> $g_iLineNum Then   ;it's changed
            $g_iOldLineNum = $g_iLineNum    ;so update
            $sMsg = "Line: " & $g_iLineNum + 1 & " / " & _GUICtrlEdit_GetLineCount($g_hEdit)    ;+1 as Zero based
            _GUICtrlStatusBar_SetText($g_hStatus, $sMsg, 0)     ;Part 0 to show Line:
        EndIf

        ;check to see if resizing occurred for possible dynamic adjustment of Line Number Edit box
        ;probably need to learn to do this in Func WM_SIZE
        _ResizeLN()
        _SyncLN()

    WEnd    ;End main body loop
    ;MAIN loop END

EndFunc     ;Func _MAINLoop()


Func  Pause($text="")
    ;__scrolltext("Debug: Paused " & $text & @CRLF)
    MsgBox(262144, "DEBUG", "Paused: " & $text)
EndFunc     ;Func  Pause($text="")

 

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

×
×
  • Create New...