taurus905 Posted April 11, 2022 Share Posted April 11, 2022 (edited) I'd first like to thank Jon for creating AutoIt. Also, thank you to all the developers for the countless hours they selflessly devote to keeping it going. And lastly thank you to all the people of this forum who offer their guidance to people like me. I've been using AutoIt since 2005 and owe my IT career to all these people. The "GUIScrollbars_Ex.au3" UDF, developed by Melba23, has opened the door to many possibilities for me. Melba23 has been one of the best, all time, at contributing to AutoIt and this forum. For a number of days, I've been trying to resolve what I believe is my logic issue. I'm creating a script which can be dynamically resized, depending on the size of the controls. My issue is I can't get the buttons to space evenly at the bottom of the gui. I'm using AutoIt v3.3.16.0 and the "GUIScrollbars_Ex.au3" UDF I downloaded again on April 4th. The below script is only dealing with the number of rows changing. But once this is resolved, I'd like to apply it to the number of columns changing also. Thank you for the direction anyone may have to offer. taurus905 expandcollapse popup; Resizing Gui with Scrollbar Example.au3 #include <WindowsConstants.au3> ; $WS_EX_TOOLWINDOW #include <GUIScrollbars_Ex.au3> ; _GUIScrollbars_Generate #include <GUIConstantsEx.au3> ; $GUI_EVENT_CLOSE HotKeySet("{PAUSE}", "_Increment_Row") ; Increment Row HotKeySet("{ESC}", "_Exit") ; Exit ; _Create_Gui() ; Create Gui Global $h_Gui Global $i_Key_Width = 40 Global $i_Key_Height = 20 Global $i_Row_Increment = 2 Global $i_Rows = 8 Global $i_Cols = 4 Global $i_Gui_Width = $i_Key_Width * $i_Cols Global $i_Gui_Height ; _Create_Schrollbars() ; Create Schrollbars Global $i_Gui_Titlebar_Height = 27 Global $i_Gui_Boarder = 3 Global $i_Aperture_Width = $i_Key_Width * $i_Cols + _ 2 * $i_Gui_Boarder Global $i_Aperture_Height Global $i_Scrollbar_Size = 17 Global $f_Scrollbar_Horz = 0 Global $f_Scrollbar_Vert = 1 ; _Create_Keys() ; Create Keys Global $s_Key_Name MsgBox(262208, _ ; $MB_TOPMOST + $MB_ICONINFORMATION "Resizing Gui with Scrollbar Example", _ "Use the 'Pause' key to increment Gui rows" & @CRLF & @CRLF & _ "and the 'Escape' key to exit script." & @CRLF & @CRLF & _ "Scroll to end of Gui to see row of keys" & @CRLF & _ "which shows inconsistent spacing.") _Increment_Row() ; Increment Row While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd Exit Func _Increment_Row() ; Increment Row GUIDelete($h_Gui) $i_Rows += $i_Row_Increment $i_Gui_Height = $i_Key_Height * $i_Rows _Create_Gui() ; Create Gui $i_Aperture_Height = $i_Key_Height * $i_Rows * .5 + _ $i_Gui_Titlebar_Height + _ $i_Gui_Boarder _Create_Schrollbars() ; Create Schrollbars _Create_Keys() ; Create Keys GUISetState(@SW_SHOW, $h_Gui) EndFunc ; ==> _Increment_Row Func _Create_Gui() ; Create Gui $h_Gui = GUICreate("Resizing Gui", _ $i_Gui_Width, _ $i_Gui_Height, _ Default, _ Default, _ Default, _ BitOR($WS_EX_TOOLWINDOW, _ $WS_EX_TOPMOST)) GUISetBkColor(0x000000) ; Black EndFunc ; ==> _Create_Gui Func _Create_Schrollbars() ; Create Schrollbars WinMove($h_Gui, "", _ Default, _ Default, _ $i_Aperture_Width + $i_Scrollbar_Size, _ $i_Aperture_Height) _GUIScrollbars_Generate($h_Gui, _ $i_Gui_Width, _ $i_Gui_Height - $i_Scrollbar_Size, _ 0, _ 0, _ Default, _ 7) ; Number of lines/chars moved by a single cursor key press - default 0 _GUIScrollBars_ShowScrollBar($h_Gui, $SB_HORZ, $f_Scrollbar_Horz) _GUIScrollBars_ShowScrollBar($h_Gui, $SB_VERT, $f_Scrollbar_Vert) EndFunc ; ==> _Create_Schrollbars Func _Create_Keys() ; Create Keys For $row = 0 To $i_Rows - 1 For $col = 0 To $i_Cols - 1 $s_Key_Name = $row + 1 & "." & $col + 1 GUICtrlCreateButton($s_Key_Name, _ ($col) * $i_Key_Width, _ ($row) * $i_Key_Height, _ $i_Key_Width, _ $i_Key_Height) GUICtrlSetTip(-1, _ $i_Key_Width & "w x " & _ $i_Key_Height & "h x " & _ $i_Rows & " rows") GUICtrlSetBkColor(-1, _ 0xFFFFFF) ; White GUICtrlSetFont(-1, _ Default, _ 900) ; Bold Next Next EndFunc ; ==> _Create_Keys Func _Exit() ; Exit Exit EndFunc ; ==> _Exit Edited April 16, 2022 by Melba23 Amended title given later posts pixelsearch 1 "Never mistake kindness for weakness."-- Author Unknown --"The highest point to which a weak but experienced mind can rise is detecting the weakness of better men."-- Georg Lichtenberg --Simple Obfuscator (Beta not needed.), Random names for Vars and Funcs Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted April 12, 2022 Moderators Share Posted April 12, 2022 taurus905, Thank you for the kind words - much appreciated. To have correctly-sized scrollbars in a fixed size GUI with a dynamic number of internal controls you need to use _GUIScrollbars_Size, not _GUIScrollbarsEx. The _GUIScrollbars_Size_Example_2 script in the UDF package shows how to use that include file when dealing with a vertical scrollbar - it is a simple matter of duplicating the same logic and adding a new handler to deal with the horizontal case. Have a go at rewriting your script yourself - you know where I am if you run into problems. M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
taurus905 Posted April 12, 2022 Author Share Posted April 12, 2022 Thank you for the direction, Melba23. I appreciate your quick response and you taking the time to analysis my issue. taurus905 "Never mistake kindness for weakness."-- Author Unknown --"The highest point to which a weak but experienced mind can rise is detecting the weakness of better men."-- Georg Lichtenberg --Simple Obfuscator (Beta not needed.), Random names for Vars and Funcs Link to comment Share on other sites More sharing options...
taurus905 Posted April 12, 2022 Author Share Posted April 12, 2022 Melba23, I don't believe my issue is with resizing the Gui. My previous example was created to show how the number of rows impacted how the last row would improperly display with respect to the length of the window. I think my real issue is my understanding of how the Gui and the Aperture relate. And also how the other components need to be accounted for, such as, the Titlebar, Scrollbar and Gui Boarders. Here is a simpler script with 12 rows and no incremental examples. Thank you again for taking the time to look at the problem I'm experiencing. taurus905 expandcollapse popup; 12 Rows of Keys with Scrollbar Example.au3 Opt("MustDeclareVars", 1) #include <WindowsConstants.au3> ; $WS_EX_TOOLWINDOW #include <GUIScrollbars_Ex.au3> ; _GUIScrollbars_Generate ; _Create_Gui() ; Create Gui Global $h_Gui Global $i_Key_Width = 40 Global $i_Key_Height = 20 Global $i_Rows = 12 Global $i_Cols = 1 Global $i_Gui_Width = $i_Key_Width * $i_Cols Global $i_Gui_Height = $i_Key_Height * $i_Rows ; _Create_Schrollbars() ; Create Schrollbars Global $i_Gui_Titlebar_Height = 27 Global $i_Gui_Boarder = 3 Global $i_Aperture_Width = $i_Key_Width * $i_Cols + _ 2 * $i_Gui_Boarder Global $i_Aperture_Height Global $i_Scrollbar_Size = 17 ; _Create_Keys() ; Create Keys Global $s_Key_Name _Create_Gui() ; Create Gui While 1 Switch GUIGetMsg() Case -3 ExitLoop EndSwitch WEnd Exit Func _Create_Gui() ; Create Gui $h_Gui = GUICreate("12 Rows Gui", _ $i_Gui_Width, _ $i_Gui_Height, _ Default, _ Default, _ Default, _ BitOR($WS_EX_TOOLWINDOW, _ $WS_EX_TOPMOST)) GUISetBkColor(0x000000) ; Black $i_Aperture_Height = $i_Key_Height * $i_Rows * .5 + _ $i_Gui_Titlebar_Height + _ $i_Gui_Boarder _Create_Schrollbars() ; Create Schrollbars _Create_Keys() ; Create Keys GUISetState(@SW_SHOW, $h_Gui) EndFunc ; ==> _Create_Gui Func _Create_Schrollbars() ; Create Schrollbars WinMove($h_Gui, "", _ Default, _ Default, _ $i_Aperture_Width + $i_Scrollbar_Size, _ $i_Aperture_Height) _GUIScrollbars_Generate($h_Gui, _ $i_Gui_Width, _ $i_Gui_Height - $i_Scrollbar_Size, _ 0, _ 0, _ Default, _ 7) ; Number of lines/chars moved by a single cursor key press - default 0 _GUIScrollBars_ShowScrollBar($h_Gui, $SB_VERT, 1) EndFunc ; ==> _Create_Schrollbars Func _Create_Keys() ; Create Keys For $row = 0 To $i_Rows - 1 For $col = 0 To $i_Cols - 1 $s_Key_Name = $row + 1 & "." & $col + 1 GUICtrlCreateButton($s_Key_Name, _ ($col) * $i_Key_Width, _ ($row) * $i_Key_Height, _ $i_Key_Width, _ $i_Key_Height) GUICtrlSetTip(-1, _ $i_Key_Width & "w x " & _ $i_Key_Height & "h x " & _ $i_Rows & " rows") GUICtrlSetBkColor(-1, _ 0xFFFFFF) ; White GUICtrlSetFont(-1, _ Default, _ 900) ; Bold Next Next EndFunc ; ==> _Create_Keys "Never mistake kindness for weakness."-- Author Unknown --"The highest point to which a weak but experienced mind can rise is detecting the weakness of better men."-- Georg Lichtenberg --Simple Obfuscator (Beta not needed.), Random names for Vars and Funcs Link to comment Share on other sites More sharing options...
taurus905 Posted April 12, 2022 Author Share Posted April 12, 2022 Here are two screenshots of the Gui to show how the Keys display above and below the fold: "Never mistake kindness for weakness."-- Author Unknown --"The highest point to which a weak but experienced mind can rise is detecting the weakness of better men."-- Georg Lichtenberg --Simple Obfuscator (Beta not needed.), Random names for Vars and Funcs Link to comment Share on other sites More sharing options...
pixelsearch Posted April 13, 2022 Share Posted April 13, 2022 (edited) Hi taurus905 Following Melba23's advice, I tried _GUIScrollbars_Size on a lighter version of your 1st script. Results are accurate until a hundred buttons are displayed. After that... expandcollapse popup; Resizing Gui with Scrollbar Example.au3 #include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #include "GUIScrollbars_Size.au3" Opt("MustDeclareVars", 1) HotKeySet("{PAUSE}", "_Increment_Row") ; Increment Row HotKeySet("{ESC}", "_Exit") ; Exit ; _Create_Gui() ; Create Gui Global $h_Gui Global $i_Key_Width = 40 Global $i_Key_Height = 32 Global $i_Row_Increment = 2 Global $i_Rows = 10 Global $i_Cols = 4 Global $i_Gui_Width = $i_Key_Width * $i_Cols Global $i_Gui_Height ; _Create_Schrollbars() ; Create Schrollbars Global $i_Scrollbar_Size = 17 ; _Create_Keys() ; Create Keys Global $s_Key_Name MsgBox(262208, _ ; $MB_TOPMOST + $MB_ICONINFORMATION "Resizing Gui with Scrollbar Example", _ "Use the 'Pause' key to increment Gui rows" & @CRLF & @CRLF & _ "and the 'Escape' key to exit script." & @CRLF & @CRLF & _ "Scroll to end of Gui to see row of keys" & @CRLF & _ "which shows (in)consistent spacing.") GUIRegisterMsg($WM_VSCROLL, "_Scrollbars_WM_VSCROLL") _Increment_Row() ; Increment Row While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $GUI_EVENT_RESTORE _GUIScrollbars_Restore($h_GUI, True, False) EndSwitch WEnd ;============================================== Func _Increment_Row() ; Increment Row GUIDelete($h_Gui) $i_Rows += $i_Row_Increment $i_Gui_Height = $i_Key_Height * $i_Rows _Create_Gui() ; Create Gui _Create_Schrollbars() ; Create Schrollbars _Create_Keys() ; Create Keys GUISetState(@SW_SHOW, $h_Gui) EndFunc ; ==> _Increment_Row ;============================================== Func _Create_Gui() ; Create Gui $h_Gui = GUICreate("Resizing Gui", _ $i_Gui_Width + $i_Scrollbar_Size, _ $i_Gui_Height / 2, _ Default, _ Default, _ Default, _ $WS_EX_TOPMOST) GUISetBkColor(0x000000) ; Black EndFunc ; ==> _Create_Gui ;============================================== Func _Create_Schrollbars() ; Create Schrollbars Local $aRet = _GUIScrollbars_Size(0, $i_Gui_Height - 9, $i_Gui_Width + $i_Scrollbar_Size, $i_Gui_Height / 2) _GUIScrollBars_Init($h_GUI) _GUIScrollBars_ShowScrollBar($h_GUI, $SB_VERT, True) _GUIScrollBars_ShowScrollBar($h_GUI, $SB_HORZ, False) _GUIScrollBars_SetScrollInfoPage($h_GUI, $SB_VERT, $aRet[2]) _GUIScrollBars_SetScrollInfoMax($h_GUI, $SB_VERT, $aRet[3]) EndFunc ; ==> _Create_Schrollbars ;============================================== Func _Create_Keys() ; Create Keys For $row = 0 To $i_Rows - 1 For $col = 0 To $i_Cols - 1 $s_Key_Name = $row + 1 & "." & $col + 1 GUICtrlCreateButton($s_Key_Name, _ ($col) * $i_Key_Width, _ ($row) * $i_Key_Height, _ $i_Key_Width, _ $i_Key_Height) GUICtrlSetTip(-1, _ $i_Key_Width & "w x " & _ $i_Key_Height & "h x " & _ $i_Rows & " rows") GUICtrlSetBkColor(-1, _ 0xFFFFFF) ; White GUICtrlSetFont(-1, _ Default, _ 900) ; Bold Next Next EndFunc ; ==> _Create_Keys ;============================================== Func _Exit() ; Exit Exit EndFunc ; ==> _Exit ;============================================== Func _Scrollbars_WM_VSCROLL($hWnd, $Msg, $wParam, $lParam) #forceref $Msg, $wParam, $lParam Local $nScrollCode = BitAND($wParam, 0x0000FFFF) Local $iIndex = -1, $yChar, $yPos Local $Min, $Max, $Page, $Pos, $TrackPos For $x = 0 To UBound($__g_aSB_WindowInfo) - 1 If $__g_aSB_WindowInfo[$x][0] = $hWnd Then $iIndex = $x $yChar = $__g_aSB_WindowInfo[$iIndex][3] ExitLoop EndIf Next If $iIndex = -1 Then Return 0 Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT) $Min = DllStructGetData($tSCROLLINFO, "nMin") $Max = DllStructGetData($tSCROLLINFO, "nMax") $Page = DllStructGetData($tSCROLLINFO, "nPage") $yPos = DllStructGetData($tSCROLLINFO, "nPos") $Pos = $yPos $TrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos") Switch $nScrollCode Case $SB_TOP DllStructSetData($tSCROLLINFO, "nPos", $Min) Case $SB_BOTTOM DllStructSetData($tSCROLLINFO, "nPos", $Max) Case $SB_LINEUP DllStructSetData($tSCROLLINFO, "nPos", $Pos - 1) Case $SB_LINEDOWN DllStructSetData($tSCROLLINFO, "nPos", $Pos + 1) Case $SB_PAGEUP DllStructSetData($tSCROLLINFO, "nPos", $Pos - $Page) Case $SB_PAGEDOWN DllStructSetData($tSCROLLINFO, "nPos", $Pos + $Page) Case $SB_THUMBTRACK DllStructSetData($tSCROLLINFO, "nPos", $TrackPos) EndSwitch DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS) _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO) _GUIScrollBars_GetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO) $Pos = DllStructGetData($tSCROLLINFO, "nPos") If ($Pos <> $yPos) Then _GUIScrollBars_ScrollWindow($hWnd, 0, $yChar * ($yPos - $Pos)) $yPos = $Pos EndIf Return $GUI_RUNDEFMSG EndFunc ;==>_Scrollbars_WM_VSCROLL Hope it helps Edit: do not use the script above. There are more robust scripts in the posts below. Edited April 17, 2022 by pixelsearch typo Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted April 13, 2022 Moderators Share Posted April 13, 2022 (edited) taurus905, Quote I think my real issue is my understanding of how the Gui and the Aperture relate The "aperture" is the size of the visible GUI in which the scrollbars are placed - the "GUI" is the underlying area which holds the controls and is scrolled into view within the aperture, this is obviously larger than the aperture or there would be no need to scroll! Quote how the other components need to be accounted for, such as, the Titlebar, Scrollbar and Gui Boarders You can ignore them - the scrollbars only deal with the internal "client" area. Here are 2 scripts which I hope will give you a clear idea of how the 2 UDFs work. Firstly a GUIScrollbars_Ex script using hard-coded row/column values to show how easy it is to get the scrollbars sized: expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include "GUIScrollbars_Ex.au3" Global $i_Key_Width = 40 Global $i_Key_Height = 20 Global $i_Rows = 12 Global $i_Cols = 4 ; Calculate the size of the full GUI to be scrolled Global $i_Gui_Width = $i_Key_Width * $i_Cols Global $i_Gui_Height = $i_Key_Height * $i_Rows ; Create the GUI with the size of the aperture to be used Global $hGUI = GUICreate("Test", 200, 200) ; Next create the keys in the full sized GUI _Create_Keys() GUISetState() ; Now generate the scrollbars using the size of the underlying GUI to be scrolled _GUIScrollbars_Generate($hGUI, $i_Gui_Width, $i_Gui_Height) ; You could also use the "Tight" parameter to minimize the margins if desired, but I would recommend not doing so While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit EndSwitch ; The latest version of the _Ex UDF now uses this function rather then the _MINIMIZE/_RESTORE event calls _GUIScrollbars_EventMonitor() WEnd Func _Create_Keys() ; Create Keys For $row = 0 To $i_Rows - 1 For $col = 0 To $i_Cols - 1 $s_Key_Name = $row + 1 & "." & $col + 1 GUICtrlCreateButton($s_Key_Name, ($col) * $i_Key_Width, ($row) * $i_Key_Height, $i_Key_Width, $i_Key_Height) ;GUICtrlSetBkColor(-1, 0xFFFFFF) ; White ; Very bad idea <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< GUICtrlSetFont(-1, Default, 900) ; Bold Next Next EndFunc ; ==> _Create_Keys Play with the $i_Rows and $i_Cols values between runs to see how the UDF copes with the different values. Now a GUIScrollbars_Size script to show how you can deal with changing the number of controls in the underlying GUI during execution: expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <GUIScrollBars.au3> #include <ScrollBarConstants.au3> #include "GUIScrollbars_Size.au3" HotKeySet("^+R", "_Increase_Rows") Global $i_Key_Width = 40 Global $i_Key_Height = 20 Global $i_Rows = 12 Global $i_Cols = 4 ; Calculate the size of the full GUI to be scrolled Global $i_Gui_Width = $i_Key_Width * $i_Cols Global $i_Gui_Height = $i_Key_Height * $i_Rows ; Create the GUI with the size of the aperture to be used Global $hGUI = GUICreate("Test", 200, 200) GUISetState() If $i_Gui_Height <= 200 Then $i_Gui_Height = 0 EndIf ; Only interested in vertical scrollbar at present $aRet = _GUIScrollbars_Size(0, $i_Gui_Height, 200, 200) ; Parameters: 0 - No horizontal scroll needed ; $i_Gui_Height - Vertical size of underlying GUI ; 200 - Width of aperture GUI ; 200 - Height of aperture GUI ; Register the vertical handler GUIRegisterMsg($WM_VSCROLL, "_Scrollbars_WM_VSCROLL") ; Create and set parameters for the vertical scrollbar _GUIScrollBars_Init($hGUI) _GUIScrollBars_ShowScrollBar($hGUI, $SB_VERT, True) _GUIScrollBars_SetScrollInfoPage($hGUI, $SB_VERT, $aRet[2]) _GUIScrollBars_SetScrollInfoMax($hGUI, $SB_VERT, $aRet[3]) ; Hide horizontal scrollbar _GUIScrollBars_ShowScrollBar($hGUI, $SB_HORZ, False) ; Create keys _Create_Keys() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $GUI_EVENT_RESTORE ; Still needed if you use the _Size UDF _GUIScrollbars_Restore($hGUI, True, False) EndSwitch WEnd Func _Increase_Rows() ; Save current final row Local $iCurrRows = $i_Rows ; Add rows $i_Rows += 4 ; create the new keys _Create_Keys($iCurrRows) ; Calculate the new height $i_Gui_Height = $i_Key_Height * $i_Rows ; Use the UDF to get the new scrollbar parameters $aRet = _GUIScrollbars_Size(0, $i_Gui_Height, 200, 200) ; And set them _GUIScrollBars_SetScrollInfoPage($hGUI, $SB_VERT, $aRet[2]) _GUIScrollBars_SetScrollInfoMax($hGUI, $SB_VERT, $aRet[3]) EndFunc Func _Create_Keys($iCurrRows = 0) ; Create Keys For $row = $iCurrRows To $i_Rows - 1 For $col = 0 To $i_Cols - 1 $s_Key_Name = $row + 1 & "." & $col + 1 GUICtrlCreateButton($s_Key_Name, ($col) * $i_Key_Width, ($row) * $i_Key_Height, $i_Key_Width, $i_Key_Height) ;GUICtrlSetBkColor(-1, 0xFFFFFF) ; White ; Very bad idea <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< GUICtrlSetFont(-1, Default, 900) ; Bold Next Next EndFunc ; ==> _Create_Keys Func _Scrollbars_WM_VSCROLL($hWnd, $Msg, $wParam, $lParam) #forceref $Msg, $wParam, $lParam Local $nScrollCode = BitAND($wParam, 0x0000FFFF) Local $iIndex = -1, $yChar, $yPos Local $Min, $Max, $Page, $Pos, $TrackPos For $x = 0 To UBound($__g_aSB_WindowInfo) - 1 If $__g_aSB_WindowInfo[$x][0] = $hWnd Then $iIndex = $x $yChar = $__g_aSB_WindowInfo[$iIndex][3] ExitLoop EndIf Next If $iIndex = -1 Then Return 0 Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT) $Min = DllStructGetData($tSCROLLINFO, "nMin") $Max = DllStructGetData($tSCROLLINFO, "nMax") $Page = DllStructGetData($tSCROLLINFO, "nPage") $yPos = DllStructGetData($tSCROLLINFO, "nPos") $Pos = $yPos $TrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos") Switch $nScrollCode Case $SB_TOP DllStructSetData($tSCROLLINFO, "nPos", $Min) Case $SB_BOTTOM DllStructSetData($tSCROLLINFO, "nPos", $Max) Case $SB_LINEUP DllStructSetData($tSCROLLINFO, "nPos", $Pos - 1) Case $SB_LINEDOWN DllStructSetData($tSCROLLINFO, "nPos", $Pos + 1) Case $SB_PAGEUP DllStructSetData($tSCROLLINFO, "nPos", $Pos - $Page) Case $SB_PAGEDOWN DllStructSetData($tSCROLLINFO, "nPos", $Pos + $Page) Case $SB_THUMBTRACK DllStructSetData($tSCROLLINFO, "nPos", $TrackPos) EndSwitch DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS) _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO) _GUIScrollBars_GetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO) $Pos = DllStructGetData($tSCROLLINFO, "nPos") If ($Pos <> $yPos) Then _GUIScrollBars_ScrollWindow($hWnd, 0, $yChar * ($yPos - $Pos)) $yPos = $Pos EndIf Return $GUI_RUNDEFMSG EndFunc ;==>_Scrollbars_WM_VSCROLL Each time the number of controls is increased, the UDF calculates the correct parameters to use when resetting the scrollbars to ensure that they are correctly sized to match the new height of the underlying GUI. I hope this clarifies how to use the 2 UDFs - do not hesitate to ask if you need further explanation. M23 P.S. And as mentioned in the comments - DO NOT colour buttons - it leads to all sorts of problems as explained here. Edit: And here is an example which is dynamic in both directions: expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <GUIScrollBars.au3> #include <ScrollBarConstants.au3> #include <WinAPISys.au3> #include "GUIScrollbars_Size.au3" HotKeySet("^+R", "_Increase_Rows") HotKeySet("^+C", "_Increase_Cols") ; Get size of scrollbars Global $iScroll_Width = _WinAPI_GetSystemMetrics(2) ; Width of VScrollbar: SM_CXVSCROLL Global $iScroll_Height = _WinAPI_GetSystemMetrics(3) ; Height of HScrollbar: SM_CYHSCROLL ; Set key parameters Global $i_Key_Width = 40 Global $i_Key_Height = 20 Global $i_Rows = 12 Global $i_Cols = 8 ; Calculate the size of the full GUI to be scrolled Global $i_Gui_Width = $i_Key_Width * $i_Cols Global $i_Gui_Height = $i_Key_Height * $i_Rows ; Create the GUI with the size of the aperture to be used Global $hGUI = GUICreate("Test", 200, 200) GUISetState() $aRet = _GUIScrollbars_Size($i_Gui_Width, $i_Gui_Height, 200, 200) ; Parameters: $i_Gui_Width - Width of underlying GUI ; $i_Gui_Height - Vertical size of underlying GUI ; 200 - Width of aperture GUI ; 200 - Height of aperture GUI ; Register the handlers GUIRegisterMsg($WM_VSCROLL, "_Scrollbars_WM_VSCROLL") GUIRegisterMsg($WM_HSCROLL, "_Scrollbars_WM_HSCROLL") ; Create scrollbars _GUIScrollBars_Init($hGUI) ;Show and set parameters for horizontal scrollbar _GUIScrollBars_ShowScrollBar($hGUI, $SB_HORZ, True) _GUIScrollBars_SetScrollInfoPage($hGUI, $SB_HORZ, $aRet[0]) _GUIScrollBars_SetScrollInfoMax($hGUI, $SB_HORZ, $aRet[1]) ; And then for vertical _GUIScrollBars_ShowScrollBar($hGUI, $SB_VERT, True) _GUIScrollBars_SetScrollInfoPage($hGUI, $SB_VERT, $aRet[2]) _GUIScrollBars_SetScrollInfoMax($hGUI, $SB_VERT, $aRet[3]) ; Create keys _Create_Keys() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $GUI_EVENT_RESTORE ; Still needed if you use the _Size UDF _GUIScrollbars_Restore($hGUI, True, False) EndSwitch WEnd Func _Increase_Cols() ; Save scrollbar positions and set to 0 Local $iHorz = _GUIScrollBars_GetScrollInfoPos($hGUI, $SB_HORZ) Local $iVert = _GUIScrollBars_GetScrollInfoPos($hGUI, $SB_VERT) _GUIScrollBars_SetScrollInfoPos($hGUI, $SB_HORZ, 0) _GUIScrollBars_SetScrollInfoPos($hGUI, $SB_VERT, 0) ; Save current final col Local $iCurrCols = $i_Cols ; Add rows $i_Cols += 4 ; Create the new keys _Create_Keys(0, $iCurrCols) ; Calculate the new height $i_Gui_Width = $i_Key_Width * $i_Cols ; Use the UDF to get the new scrollbar parameters $aRet = _GUIScrollbars_Size($i_Gui_Width + $iScroll_Width, 0, 200, 200) ; And set them _GUIScrollBars_SetScrollInfoPage($hGUI, $SB_HORZ, $aRet[0]) _GUIScrollBars_SetScrollInfoMax($hGUI, $SB_HORZ, $aRet[1]) ; Reset positions _GUIScrollBars_SetScrollInfoPos($hGUI, $SB_HORZ, $iHorz) _GUIScrollBars_SetScrollInfoPos($hGUI, $SB_VERT, $iVert) EndFunc Func _Increase_Rows() ; Save scrollbar positions and set to 0 Local $iHorz = _GUIScrollBars_GetScrollInfoPos($hGUI, $SB_HORZ) Local $iVert = _GUIScrollBars_GetScrollInfoPos($hGUI, $SB_VERT) _GUIScrollBars_SetScrollInfoPos($hGUI, $SB_HORZ, 0) _GUIScrollBars_SetScrollInfoPos($hGUI, $SB_VERT, 0) ; Save current final row Local $iCurrRows = $i_Rows ; Add rows $i_Rows += 4 ; create the new keys _Create_Keys($iCurrRows) ; Calculate the new height $i_Gui_Height = $i_Key_Height * $i_Rows ; Use the UDF to get the new scrollbar parameters $aRet = _GUIScrollbars_Size(0, $i_Gui_Height + $iScroll_Height, 200, 200) ; And set them _GUIScrollBars_SetScrollInfoPage($hGUI, $SB_VERT, $aRet[2]) _GUIScrollBars_SetScrollInfoMax($hGUI, $SB_VERT, $aRet[3]) ; Reset positions _GUIScrollBars_SetScrollInfoPos($hGUI, $SB_HORZ, $iHorz) _GUIScrollBars_SetScrollInfoPos($hGUI, $SB_VERT, $iVert) EndFunc Func _Create_Keys($iCurrRows = 0, $iCurrCols = 0) ; Create Keys For $row = $iCurrRows To $i_Rows - 1 For $col = $iCurrCols To $i_Cols - 1 $s_Key_Name = $row + 1 & "." & $col + 1 GUICtrlCreateButton($s_Key_Name, ($col) * $i_Key_Width, ($row) * $i_Key_Height, $i_Key_Width, $i_Key_Height) GUICtrlSetFont(-1, Default, 900) ; Bold Next Next EndFunc ; ==> _Create_Keys Func _Scrollbars_WM_HSCROLL($hWnd, $Msg, $wParam, $lParam) #forceref $Msg, $lParam Local $nScrollCode = BitAND($wParam, 0x0000FFFF) Local $iIndex = -1, $xChar, $xPos Local $Page, $Pos, $TrackPos For $x = 0 To UBound($__g_aSB_WindowInfo) - 1 If $__g_aSB_WindowInfo[$x][0] = $hWnd Then $iIndex = $x $xChar = $__g_aSB_WindowInfo[$iIndex][2] ExitLoop EndIf Next If $iIndex = -1 Then Return 0 Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_HORZ) $Page = DllStructGetData($tSCROLLINFO, "nPage") $xPos = DllStructGetData($tSCROLLINFO, "nPos") $Pos = $xPos $TrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos") Switch $nScrollCode Case $SB_LINELEFT DllStructSetData($tSCROLLINFO, "nPos", $Pos - 1) Case $SB_LINERIGHT DllStructSetData($tSCROLLINFO, "nPos", $Pos + 1) Case $SB_PAGELEFT DllStructSetData($tSCROLLINFO, "nPos", $Pos - $Page) Case $SB_PAGERIGHT DllStructSetData($tSCROLLINFO, "nPos", $Pos + $Page) Case $SB_THUMBTRACK DllStructSetData($tSCROLLINFO, "nPos", $TrackPos) EndSwitch DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS) _GUIScrollBars_SetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO) _GUIScrollBars_GetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO) $Pos = DllStructGetData($tSCROLLINFO, "nPos") If ($Pos <> $xPos) Then _GUIScrollBars_ScrollWindow($hWnd, $xChar * ($xPos - $Pos), 0) Return $GUI_RUNDEFMSG EndFunc ;==>_Scrollbars_WM_HSCROLL Func _Scrollbars_WM_VSCROLL($hWnd, $Msg, $wParam, $lParam) #forceref $Msg, $wParam, $lParam Local $nScrollCode = BitAND($wParam, 0x0000FFFF) Local $iIndex = -1, $yChar, $yPos Local $Min, $Max, $Page, $Pos, $TrackPos For $x = 0 To UBound($__g_aSB_WindowInfo) - 1 If $__g_aSB_WindowInfo[$x][0] = $hWnd Then $iIndex = $x $yChar = $__g_aSB_WindowInfo[$iIndex][3] ExitLoop EndIf Next If $iIndex = -1 Then Return 0 Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT) $Min = DllStructGetData($tSCROLLINFO, "nMin") $Max = DllStructGetData($tSCROLLINFO, "nMax") $Page = DllStructGetData($tSCROLLINFO, "nPage") $yPos = DllStructGetData($tSCROLLINFO, "nPos") $Pos = $yPos $TrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos") Switch $nScrollCode Case $SB_TOP DllStructSetData($tSCROLLINFO, "nPos", $Min) Case $SB_BOTTOM DllStructSetData($tSCROLLINFO, "nPos", $Max) Case $SB_LINEUP DllStructSetData($tSCROLLINFO, "nPos", $Pos - 1) Case $SB_LINEDOWN DllStructSetData($tSCROLLINFO, "nPos", $Pos + 1) Case $SB_PAGEUP DllStructSetData($tSCROLLINFO, "nPos", $Pos - $Page) Case $SB_PAGEDOWN DllStructSetData($tSCROLLINFO, "nPos", $Pos + $Page) Case $SB_THUMBTRACK DllStructSetData($tSCROLLINFO, "nPos", $TrackPos) EndSwitch DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS) _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO) _GUIScrollBars_GetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO) $Pos = DllStructGetData($tSCROLLINFO, "nPos") If ($Pos <> $yPos) Then _GUIScrollBars_ScrollWindow($hWnd, 0, $yChar * ($yPos - $Pos)) $yPos = $Pos EndIf Return $GUI_RUNDEFMSG EndFunc ;==>_Scrollbars_WM_VSCROLL Edited April 13, 2022 by Melba23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
taurus905 Posted April 13, 2022 Author Share Posted April 13, 2022 15 hours ago, pixelsearch said: Hi taurus905 Following Melba23's advice, I tried _GUIScrollbars_Size on a lighter version of your 1st script. Results are accurate until a hundred buttons are displayed. After that... Hello pixelsearch, Thank you for taking the time to help me understand how to use Melba23's UDF. People like you are a large part of the reason so many people LOVE AutoIt. I wanted to verify you are seeing the same output as I do when running your edited version of my original script. This is what I see. And each iteration after creates an ever expanding black space below the last row. "Never mistake kindness for weakness."-- Author Unknown --"The highest point to which a weak but experienced mind can rise is detecting the weakness of better men."-- Georg Lichtenberg --Simple Obfuscator (Beta not needed.), Random names for Vars and Funcs Link to comment Share on other sites More sharing options...
pixelsearch Posted April 14, 2022 Share Posted April 14, 2022 (edited) @Melba23 great 3 examples, they'll definitely help users dealing with custom Scrollbars @taurus905 thanks for the kind words. On 4/13/2022 at 11:18 PM, taurus905 said: I wanted to verify you are seeing the same output as I do when running your edited version of my original script. This is what I see. And each iteration after creates an ever expanding black space below the last row. Yes I do see the same bad output, that's why I wrote "it worked fine with approx. 100 buttons, after that..." . I can amend the code with some constants to work better... though it's not a good solution, because it will display everything correctly but we won't know what caused the issues. Only M23 or someone having knowledge in scrollbars (that's not me) could explain the issues encountered until then. If I understood you correctly, what you really want is to have the buttons match perfectly the lower edge of the GUI, without any gap or any button not showing completely. Here is a pic showing what didn't work (3 GUI's on the left) and how it can be amended to display correctly (GUI on the right) : The 3 GUI's on the left show the issue encountered in the edited script of the previous post : * Everything works fine until 26 rows are displayed (1st GUI) * An incredible horizontal scrollbar appears (God only knows why !) when 2 more rows are added (2nd GUI) * That same horizontal scrollbar disappears immediately after 2 more rows are added... but now, a gap starts to show between the last row and the bottom edge (3rd GUI). And that gap will have its size increasing, as shown on your pics in your previous post. To solve all this, I added some constants to the script below, but it's not a good solution. Also, I replaced the buttons with labels (minor change in this context). The display is now correct : see how the 4th GUI on the right shows 44 full rows in the pic above ... but I don't like at all this patch based on constants. It would be great if anyone could explain why the horizontal scrollbar appeared mysteriously in the 2nd GUI ! expandcollapse popup; Resizing Gui with Scrollbar Example.au3 #include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include "GUIScrollbars_Size.au3" Opt("MustDeclareVars", 1) HotKeySet("{PAUSE}", "_Increment_Row") ; Increment Row HotKeySet("{ESC}", "_Exit") ; Exit ; _Create_Gui() ; Create Gui Global $h_Gui Global $i_Key_Width = 40 Global $i_Key_Height = 32 Global $i_Row_Increment = 2 Global $i_Rows = 10 Global $i_Cols = 4 Global $i_Gui_Width = $i_Key_Width * $i_Cols Global $i_Gui_Height ; _Create_Schrollbars() ; Create Schrollbars Global $i_Scrollbar_Size = 17 ; _Create_Keys() ; Create Keys Global $s_Key_Name MsgBox(262208, _ ; $MB_TOPMOST + $MB_ICONINFORMATION "Resizing Gui with Scrollbar Example", _ "Use the 'Pause' key to increment Gui rows" & @CRLF & @CRLF & _ "and the 'Escape' key to exit script." & @CRLF & @CRLF & _ "Scroll to end of Gui to see row of keys" & @CRLF & _ "which shows (in)consistent spacing.") GUIRegisterMsg($WM_VSCROLL, "_Scrollbars_WM_VSCROLL") _Increment_Row() ; Increment Row While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $GUI_EVENT_RESTORE _GUIScrollbars_Restore($h_GUI, True, False) EndSwitch WEnd ;============================================== Func _Increment_Row() ; Increment Row GUIDelete($h_Gui) $i_Rows += $i_Row_Increment $i_Gui_Height = $i_Key_Height * $i_Rows _Create_Gui() ; Create Gui _Create_Schrollbars() ; Create Schrollbars _Create_Keys() ; Create Keys GUISetState(@SW_SHOW, $h_Gui) EndFunc ; ==> _Increment_Row ;============================================== Func _Create_Gui() ; Create Gui $h_Gui = GUICreate("Resizing Gui", _ $i_Gui_Width + $i_Scrollbar_Size, _ $i_Gui_Height / 2, _ Default, _ Default, _ Default, _ $WS_EX_TOPMOST) EndFunc ; ==> _Create_Gui ;============================================== Func _Create_Schrollbars() ; Create Schrollbars Local $aRet = _GUIScrollbars_Size(0, $i_Gui_Height -9, $i_Gui_Width + $i_Scrollbar_Size, $i_Gui_Height / 2) If $aRet[2] >= 30 Then ; or an increasing gap starts to appear at the bottom of the GUI Local $iInc = ($aRet[2] - 28) / 2 $aRet[2] -= 2 * $iInc $aRet[3] -= 2 * $iInc EndIf _GUIScrollBars_Init($h_GUI) _GUIScrollBars_ShowScrollBar($h_GUI, $SB_VERT, True) _GUIScrollBars_ShowScrollBar($h_GUI, $SB_HORZ, False) _GUIScrollBars_SetScrollInfoPage($h_GUI, $SB_VERT, $aRet[2]) _GUIScrollBars_SetScrollInfoMax($h_GUI, $SB_VERT, $aRet[3]) _GUIScrollBars_SetScrollInfoMax($h_GUI, $SB_HORZ, 0) ; or an horiz scrollbar appears when $aRet[2] = 28 ! EndFunc ; ==> _Create_Schrollbars ;============================================== Func _Create_Keys() ; Create Keys For $row = 0 To $i_Rows - 1 For $col = 0 To $i_Cols - 1 $s_Key_Name = $row + 1 & "." & $col + 1 GUICtrlCreateLabel($s_Key_Name, _ ($col) * $i_Key_Width, _ ($row) * $i_Key_Height, _ $i_Key_Width, _ $i_Key_Height, _ BitOr($SS_CENTERIMAGE, $SS_CENTER, $SS_SUNKEN), _ $GUI_WS_EX_PARENTDRAG) GUICtrlSetTip(-1, _ $i_Key_Width & "w x " & _ $i_Key_Height & "h x " & _ $i_Rows & " rows") GUICtrlSetBkColor(-1, _ 0xFFFFFF) ; White GUICtrlSetFont(-1, _ Default, _ 900) ; Bold Next Next EndFunc ; ==> _Create_Keys ;============================================== Func _Exit() ; Exit Exit EndFunc ; ==> _Exit ;============================================== Func _Scrollbars_WM_VSCROLL($hWnd, $Msg, $wParam, $lParam) #forceref $Msg, $wParam, $lParam Local $nScrollCode = BitAND($wParam, 0x0000FFFF) Local $iIndex = -1, $yChar, $yPos Local $Min, $Max, $Page, $Pos, $TrackPos For $x = 0 To UBound($__g_aSB_WindowInfo) - 1 If $__g_aSB_WindowInfo[$x][0] = $hWnd Then $iIndex = $x $yChar = $__g_aSB_WindowInfo[$iIndex][3] ExitLoop EndIf Next If $iIndex = -1 Then Return 0 Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT) $Min = DllStructGetData($tSCROLLINFO, "nMin") $Max = DllStructGetData($tSCROLLINFO, "nMax") $Page = DllStructGetData($tSCROLLINFO, "nPage") $yPos = DllStructGetData($tSCROLLINFO, "nPos") $Pos = $yPos $TrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos") Switch $nScrollCode Case $SB_TOP DllStructSetData($tSCROLLINFO, "nPos", $Min) Case $SB_BOTTOM DllStructSetData($tSCROLLINFO, "nPos", $Max) Case $SB_LINEUP DllStructSetData($tSCROLLINFO, "nPos", $Pos - 1) Case $SB_LINEDOWN DllStructSetData($tSCROLLINFO, "nPos", $Pos + 1) Case $SB_PAGEUP DllStructSetData($tSCROLLINFO, "nPos", $Pos - $Page) Case $SB_PAGEDOWN DllStructSetData($tSCROLLINFO, "nPos", $Pos + $Page) Case $SB_THUMBTRACK DllStructSetData($tSCROLLINFO, "nPos", $TrackPos) EndSwitch DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS) _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO) _GUIScrollBars_GetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO) $Pos = DllStructGetData($tSCROLLINFO, "nPos") If ($Pos <> $yPos) Then _GUIScrollBars_ScrollWindow($hWnd, 0, $yChar * ($yPos - $Pos)) $yPos = $Pos EndIf Return $GUI_RUNDEFMSG EndFunc ;==>_Scrollbars_WM_VSCROLL Sorry M23 for all these big pics in your thread. If you think these last posts should be placed in another thread, that's fine too. Edit: do not use the script above. There are more robust scripts in the posts below. Edited April 17, 2022 by pixelsearch Link to comment Share on other sites More sharing options...
taurus905 Posted April 14, 2022 Author Share Posted April 14, 2022 Thank you, Melba23 for your detailed explanation and three example scripts. I especially appreciate the simplicity of the first script and will build on it after studying the other two as well as the internal workings of your UDF. I remember one of my first posts in 2005 concerned the coloring of buttons. The temporary work-around was to use labels, as pixelsearch just referred to. Then later, I thought this issue was addressed and I went back to using buttons. Thank you for reminding me this may cause problems. I will keep that in mind. I'm grateful for all the time you've spent helping me. taurus905 P.S. I also apologize for all the screenshots in your thread. Please edit them as you see fit. "Never mistake kindness for weakness."-- Author Unknown --"The highest point to which a weak but experienced mind can rise is detecting the weakness of better men."-- Georg Lichtenberg --Simple Obfuscator (Beta not needed.), Random names for Vars and Funcs Link to comment Share on other sites More sharing options...
taurus905 Posted April 14, 2022 Author Share Posted April 14, 2022 30 minutes ago, pixelsearch said: Yes I do see the same bad output, that's why I wrote "it worked fine with approx. 100 buttons, after that..." . @pixelsearch I apologize for mis-reading your post. I read "100 buttons", but my mind was thinking "100 rows". If you configure the Gui from 4 columns to just 1, you will see the same behavior with only 28 buttons. Therefore, it is a function of the number of rows which causes the unexpected horizontal scrollbar. You've also described the issue precisely, pertaining to how at 30 rows the horizontal scrollbar no longer shows, but a ever increasing gap displays between the last row and the bottom edge of the Gui. Before I posted this issue a few days ago, I tried constructing some type of algorithm to inject a correct factor in order to get the desired output. But as you stated, it's not a good solution. I believe both you and Melba23 see and understand the issue as I do. That alone makes me feel a solution will be found. I am determined to have total control of my scrollbars. And by considering everyone's input, I'm sure this will happen. taurus905 "Never mistake kindness for weakness."-- Author Unknown --"The highest point to which a weak but experienced mind can rise is detecting the weakness of better men."-- Georg Lichtenberg --Simple Obfuscator (Beta not needed.), Random names for Vars and Funcs Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted April 14, 2022 Moderators Share Posted April 14, 2022 taurus905 & pixelsearch, As is explained in the tutorial in the first post of this thread (you did read it?) scrollbars - at least to my knowledge of their implementation in AutoIt - work on line height and average character width. Because of this, it is almost impossible to get the scroll to exactly fit an underlying GUI of arbitrary size - and is the reason I introduced the "tight" parameters in the _Generate call, the effects of which is shown in the graphic within the tutorial. So "total control" is probably out of the question and you are going to have to accept a degree of either positive or negative "margin" at the bottom and right of any given scrolled GUI. Of course if anyone wants to prove me wrong, I would be delighted..... M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
pixelsearch Posted April 14, 2022 Share Posted April 14, 2022 (edited) On 4/14/2022 at 10:22 AM, Melba23 said: you did read it? I sure did read it before starting all this, at least twice That's the reason why I did set $i_Key_Height to 32 in the script above (32 being 2*16, and 16 is the line height on my computer) I think the key for trying to have no vertical gap and controls fully visible is to use multiples of line height, that means buttons/labels having a height of 16 or 32 (on my computer) * First I noticed that value of 16 in your function _GUIScrollbars_Size() ; Determine GUI text size $aRet = _GSB_Size_Text($hWnd) ... $iX_Char = $aRet[0] ; 7 on my computer $iY_Char = $aRet[1] ; 16 " " " * It seems possible to retrieve that line height with a short code placed at the beginning of the script, something like this : ; Get line height Global $iLineHeight = _GSB_Size_Text(GUICreate(""))[1] GUIDelete() ; ConsoleWrite($iLineHeight & @crlf) ; 16 on my computer * Finally (and this should also help to solve taurus905 issue) 16 is also found in a global array declared in... GuiScrollBars.au3 : Global $__g_aSB_WindowInfo[1][8] ; 0 = hwnd;1 = xClientMax;2 cxChar;3 = cyChar;4 cxClient;5 = cyClient,6 = iHMax;7 = iVMax This is the content of this array during taurus905's script (which deletes the GUI and recreates it each time new rows are added, this explains why there are several rows in the array) : 7 & 16 in Col 2 & 3, I guess these values depend on the OS and may vary from a computer to the other. Now let's focus on that constant of 27 found in Col 7. That's why we are stuck with a phantom horizontal scrollbar appearing when $aRet[2] = 28, then a growing gap at the bottom of the Gui, because of the following line found in _GUIScrollBars_Init() : If $iMaxV = -1 Then $__g_aSB_WindowInfo[$iIndex][7] = 27 If we increase that value, not by changing directly 27 in the function, but by passing a 3rd parameter when calling _GUIScrollBars_Init(), then there will be no phantom horizontal scrollbar and no gap at the bottom of the GUI : The code that led to the pic above : expandcollapse popup; Resizing Gui with Vertical Scrollbar Example.au3 #include <Array.au3> #include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WinAPISys.au3> #include "GUIScrollbars_Size.au3" Opt("MustDeclareVars", 1) HotKeySet("{PAUSE}", "_Increment") ; Increment HotKeySet("{ESC}", "_Exit") ; Exit ; Get 1 character height & width (before creating GUI, as it will be used to calculate controls size) Global $aCharSize = _GSB_Size_Text(GUICreate("")) ; M23's internal function in GUIScrollbars_Size.au3 GUIDelete() Global $iCharWidth = $aCharSize[0], $iCharHeight = $aCharSize[1] ; ConsoleWrite($iCharWidth & " " & $iCharHeight & @crlf) ; 7 & 16 on my PC ; _Create_Gui() ; Create Gui Global $h_Gui Global $i_Increment = 2 Global $i_Rows = 24 Global $i_Cols = 4 Global $i_Key_Width = $iCharWidth * 6 ; 42 on my PC (7 * 6) Global $i_Key_Height = $iCharHeight * 2 ; 32 on my PC (16 * 2) Global $i_Gui_Width = $i_Key_Width * $i_Cols Global $i_Gui_Height Global $nV_Pos, $iIncMini = 0 ; _Create_Schrollbars() ; Create Schrollbars Global $iScroll_Width = _WinAPI_GetSystemMetrics(2) ; Width of VScrollbar: SM_CXVSCROLL Global $iScroll_Height = _WinAPI_GetSystemMetrics(3) ; Height of HScrollbar: SM_CYHSCROLL ; ConsoleWrite($iScroll_Width & " " & $iScroll_Height & @crlf) ; 17 & 17 on my PC ; _Create_Keys() ; Create Keys Global $s_Key_Name MsgBox(262208, _ ; $MB_TOPMOST + $MB_ICONINFORMATION "Resizing Gui with Vertical Scrollbar Example", _ "Use the 'Pause' key to increment Gui rows" & @CRLF & @CRLF & _ "and the 'Escape' key to exit script." & @CRLF & @CRLF & _ "Scroll to end of Gui to see row of keys" & @CRLF & _ "which shows consistent spacing.") GUIRegisterMsg($WM_VSCROLL, "_Scrollbars_WM_VSCROLL") _Increment() ; Increment While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch If BitAND(WinGetState($h_GUI), $WIN_STATE_MINIMIZED) Then ; Minimize button, Win-D, hide all $iIncMini += 1 If $iIncMini = 1 Then _GUIScrollBars_ShowScrollBar($h_GUI, $SB_VERT, False) $nV_Pos = _GUIScrollBars_GetScrollPos($h_GUI, $SB_VERT) _GUIScrollBars_SetScrollInfoPos($h_GUI, $SB_VERT, 0) EndIf Else ; not Minimized If $iIncMini Then $iIncMini = 0 _GUIScrollBars_ShowScrollBar($h_GUI, $SB_VERT, True) _GUIScrollBars_SetScrollInfoPos($h_GUI, $SB_VERT, $nV_Pos) _GUIScrollBars_ShowScrollBar($h_GUI, $SB_HORZ, False) ; keep that line EndIf EndIf WEnd ;======================================================== Func _Increment() ; Increment GUIDelete($h_Gui) ; As the script deletes the GUI for each increment, no need to keep useless rows... ; ... in the GLOBAL array $__g_aSB_WindowInfo[][] declared in GuiScrollBars.au3 ; But it's also a good idea to keep the "useless" rows to check the changed values. ; Global $__g_aSB_WindowInfo[1][8] ; reset, exactly as found in GuiScrollBars.au3 ; _ArrayDisplay($__g_aSB_WindowInfo, "$__g_aSB_WindowInfo", Default, $ARRAYDISPLAY_NOROW) $i_Rows += $i_Increment $i_Gui_Height = $i_Key_Height * $i_Rows _Create_Gui() ; Create Gui _Create_Schrollbars() ; Create Schrollbars _Create_Keys() ; Create Keys GUISetState(@SW_SHOW, $h_Gui) EndFunc ; ==> _Increment ;======================================================== Func _Create_Gui() ; Create Gui $h_Gui = GUICreate("Resizing Gui", _ $i_Gui_Width + $iScroll_Width, _ $i_Gui_Height / 2, _ Default, _ Default, _ Default, _ $WS_EX_TOPMOST) EndFunc ; ==> _Create_Gui ;======================================================== Func _Create_Schrollbars() ; Create Schrollbars Local $aRet = _GUIScrollbars_Size(0, $i_Gui_Height - $iScroll_Height / 2, _ $i_Gui_Width + $iScroll_Width, $i_Gui_Height / 2) ; ConsoleWrite("$aRet[2] = " & $aRet[2] & " $aRet[3] = " & $aRet[3] & @crlf) ;~ _GUIScrollBars_Init($h_GUI) ; phantom scrollbar + gap when no 2nd / 3rd param. _GUIScrollBars_Init($h_GUI, -1, 100) ; 3rd parameter to bypass the constant of 27 _GUIScrollBars_ShowScrollBar($h_GUI, $SB_VERT, True) _GUIScrollBars_ShowScrollBar($h_GUI, $SB_HORZ, False) _GUIScrollBars_SetScrollInfoPage($h_GUI, $SB_VERT, $aRet[2]) _GUIScrollBars_SetScrollInfoMax($h_GUI, $SB_VERT, $aRet[3]) EndFunc ; ==> _Create_Schrollbars ;======================================================== Func _Create_Keys() ; Create Keys For $row = 0 To $i_Rows - 1 For $col = 0 To $i_Cols - 1 $s_Key_Name = $row + 1 & "." & $col + 1 GUICtrlCreateLabel($s_Key_Name, _ ($col) * $i_Key_Width, _ ($row) * $i_Key_Height, _ $i_Key_Width, _ $i_Key_Height, _ BitOr($SS_CENTERIMAGE, $SS_CENTER, $SS_SUNKEN), _ $GUI_WS_EX_PARENTDRAG) GUICtrlSetTip(-1, _ $i_Key_Width & "w x " & _ $i_Key_Height & "h x " & _ $i_Rows & " rows") GUICtrlSetBkColor(-1, _ 0xFFFFFF) ; White GUICtrlSetFont(-1, _ Default, _ 900) ; Bold Next Next EndFunc ; ==> _Create_Keys ;======================================================== Func _Exit() ; Exit Exit EndFunc ; ==> _Exit ;======================================================== Func _Scrollbars_WM_VSCROLL($hWnd, $Msg, $wParam, $lParam) #forceref $Msg, $wParam, $lParam Local $nScrollCode = BitAND($wParam, 0x0000FFFF) Local $iIndex = -1, $yChar, $yPos Local $Min, $Max, $Page, $Pos, $TrackPos For $x = 0 To UBound($__g_aSB_WindowInfo) - 1 If $__g_aSB_WindowInfo[$x][0] = $hWnd Then $iIndex = $x $yChar = $__g_aSB_WindowInfo[$iIndex][3] ExitLoop EndIf Next If $iIndex = -1 Then Return 0 Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT) $Min = DllStructGetData($tSCROLLINFO, "nMin") $Max = DllStructGetData($tSCROLLINFO, "nMax") $Page = DllStructGetData($tSCROLLINFO, "nPage") $yPos = DllStructGetData($tSCROLLINFO, "nPos") $Pos = $yPos $TrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos") Switch $nScrollCode Case $SB_TOP DllStructSetData($tSCROLLINFO, "nPos", $Min) Case $SB_BOTTOM DllStructSetData($tSCROLLINFO, "nPos", $Max) Case $SB_LINEUP DllStructSetData($tSCROLLINFO, "nPos", $Pos - 1) Case $SB_LINEDOWN DllStructSetData($tSCROLLINFO, "nPos", $Pos + 1) Case $SB_PAGEUP DllStructSetData($tSCROLLINFO, "nPos", $Pos - $Page) Case $SB_PAGEDOWN DllStructSetData($tSCROLLINFO, "nPos", $Pos + $Page) Case $SB_THUMBTRACK DllStructSetData($tSCROLLINFO, "nPos", $TrackPos) EndSwitch DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS) _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO) _GUIScrollBars_GetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO) $Pos = DllStructGetData($tSCROLLINFO, "nPos") If ($Pos <> $yPos) Then _GUIScrollBars_ScrollWindow($hWnd, 0, $yChar * ($yPos - $Pos)) $yPos = $Pos EndIf Return $GUI_RUNDEFMSG EndFunc ;==>_Scrollbars_WM_VSCROLL I was lucky to find that global array $__g_aSB_WindowInfo[1][8] and its constant of 27, even if it took a long time. I hope the explanations above are correct and it may help @taurus905 to achieve his goal Edited April 17, 2022 by pixelsearch While... Wend loop more robust, taking care of Minimize button, Win-D, hide all taurus905 1 Link to comment Share on other sites More sharing options...
taurus905 Posted April 14, 2022 Author Share Posted April 14, 2022 3 hours ago, pixelsearch said: I was lucky to find that global array $__g_aSB_WindowInfo[1][8] and its constant of 27, even if it took a long time. I hope the explanations above are correct and it may help @taurus905 to achieve his goal @pixelsearchWow! Very good detective work, my friend. You solved this much quicker than I ever would have, if ever. I at least owe you a pint, or a coffee if you'd prefer. taurus905 "Never mistake kindness for weakness."-- Author Unknown --"The highest point to which a weak but experienced mind can rise is detecting the weakness of better men."-- Georg Lichtenberg --Simple Obfuscator (Beta not needed.), Random names for Vars and Funcs Link to comment Share on other sites More sharing options...
pixelsearch Posted April 16, 2022 Share Posted April 16, 2022 (edited) On 4/14/2022 at 12:35 AM, taurus905 said: I at least owe you a pint, or a coffee if you'd prefer. Thank you, let's have both Ok, my preceding post tested a vertical scrollbar and showed a possible issue in the function _GUIScrollBars_Init() found in GuiScrollBars.au3, because of a constant = 27, when the function is called with only 1 argument : Func _GUIScrollBars_Init($hWnd, $iMaxH = -1, $iMaxV = -1) ... If $iMaxV = -1 Then $__g_aSB_WindowInfo[$iIndex][7] = 27 ... EndFunc Now let's start some tests with an horizontal scrollbar, which will show a similar issue : The code corresponding to the pic above will be found below. Meanwhile : * 1st & 2nd gui are correct : no vertical phantom scrollbar, no gap. * 3rd gui shows a non-draggable vertical phantom scrollbar. * 4th gui shows a gap at the right, which would increase indefinitely when you add columns. Starting with 3rd gui, the issue appears because of the following line : Func _GUIScrollBars_Init($hWnd, $iMaxH = -1, $iMaxV = -1) ... If $iMaxH = -1 Then $__g_aSB_WindowInfo[$iIndex][1] = 48 * $iXAmount + 12 * $iUpperX ... EndFunc Do you notice this value of 462 in Col1 of all preceding ArrayDisplay's ? This is the value of $__g_aSB_WindowInfo[$iIndex][1] on my computer. As soon as the value in Col4 (cxClient) becomes superior to 462, then a vertical non-draggable phantom scrollbar & gap will appear. A possible solution is to increase this value of 462 when calling _GUIScrollBars_Init(), like this : ; _GUIScrollBars_Init($h_GUI) ; phantom scrollbar + gap when no 2nd / 3rd param. _GUIScrollBars_Init($h_GUI, 1500) ; 2nd parameter passed to avoid phantom scrollbar + gap Then everything comes back to normal : Code corresponding to these pics : expandcollapse popup; Resizing Gui with Horizontal Scrollbar Example.au3 #include <Array.au3> #include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WinAPISys.au3> #include "GUIScrollbars_Size.au3" Opt("MustDeclareVars", 1) HotKeySet("{PAUSE}", "_Increment") ; Increment HotKeySet("{ESC}", "_Exit") ; Exit ; Get 1 character height & width (before creating GUI, as it will be used to calculate controls size) Global $aCharSize = _GSB_Size_Text(GUICreate("")) ; M23's internal function in GUIScrollbars_Size.au3 GUIDelete() Global $iCharWidth = $aCharSize[0], $iCharHeight = $aCharSize[1] ; ConsoleWrite($iCharWidth & " " & $iCharHeight & @crlf) ; 7 & 16 on my PC ; _Create_Gui() ; Create Gui Global $h_Gui Global $i_Increment = 2 Global $i_Rows = 6 Global $i_Cols = 8 Global $i_Key_Width = $iCharWidth * 10 ; 70 on my PC (7 * 10) Global $i_Key_Height = $iCharHeight * 1 ; 16 on my PC (16 * 1) Global $i_Gui_Width Global $i_Gui_Height = $i_Key_Height * $i_Rows Global $nH_Pos, $iIncMini = 0 ; _Create_Schrollbars() ; Create Schrollbars Global $iScroll_Width = _WinAPI_GetSystemMetrics(2) ; Width of VScrollbar: SM_CXVSCROLL Global $iScroll_Height = _WinAPI_GetSystemMetrics(3) ; Height of HScrollbar: SM_CYHSCROLL ; ConsoleWrite($iScroll_Width & " " & $iScroll_Height & @crlf) ; 17 & 17 on my PC ; _Create_Keys() ; Create Keys Global $s_Key_Name MsgBox(262208, _ ; $MB_TOPMOST + $MB_ICONINFORMATION "Resizing Gui with Horizontal Scrollbar Example", _ "Use the 'Pause' key to increment Gui cols" & @CRLF & @CRLF & _ "and the 'Escape' key to exit script." & @CRLF & @CRLF & _ "Scroll to end of Gui to see cols of keys" & @CRLF & _ "which shows consistent spacing.") GUIRegisterMsg($WM_HSCROLL, "_Scrollbars_WM_HSCROLL") _Increment() ; Increment While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch If BitAND(WinGetState($h_GUI), $WIN_STATE_MINIMIZED) Then ; Minimize button, Win-D, hide all $iIncMini += 1 If $iIncMini = 1 Then _GUIScrollBars_ShowScrollBar($h_GUI, $SB_HORZ, False) $nH_Pos = _GUIScrollBars_GetScrollPos($h_GUI, $SB_HORZ) _GUIScrollBars_SetScrollInfoPos($h_GUI, $SB_HORZ, 0) EndIf Else ; not Minimized If $iIncMini Then $iIncMini = 0 _GUIScrollBars_ShowScrollBar($h_GUI, $SB_HORZ, True) _GUIScrollBars_SetScrollInfoPos($h_GUI, $SB_HORZ, $nH_Pos) _GUIScrollBars_ShowScrollBar($h_GUI, $SB_VERT, False) ; keep that line EndIf EndIf WEnd ;============================================== Func _Increment() ; Increment GUIDelete($h_Gui) ; As the script deletes the GUI for each increment, no need to keep useless rows... ; ... in the GLOBAL array $__g_aSB_WindowInfo[][] declared in GuiScrollBars.au3 ; But it's also a good idea to keep the "useless" rows to check the changed values. ; Global $__g_aSB_WindowInfo[1][8] ; reset, exactly as found in GuiScrollBars.au3 ; _ArrayDisplay($__g_aSB_WindowInfo, "$__g_aSB_WindowInfo", Default, $ARRAYDISPLAY_NOROW) $i_Cols += $i_Increment $i_Gui_Width = $i_Key_Width * $i_Cols _Create_Gui() ; Create Gui _Create_Schrollbars() ; Create Schrollbars _Create_Keys() ; Create Keys GUISetState(@SW_SHOW, $h_Gui) EndFunc ; ==> _Increment ;======================================================== Func _Create_Gui() ; Create Gui $h_Gui = GUICreate("Resizing Gui", _ $i_Gui_Width / 2, _ $i_Gui_Height + $iScroll_Height, _ Default, _ Default, _ Default, _ $WS_EX_TOPMOST) EndFunc ; ==> _Create_Gui ;======================================================== Func _Create_Schrollbars() ; Create Schrollbars Local $aRet = _GUIScrollbars_Size($i_Gui_Width - $iScroll_Width / 2, 0, _ $i_Gui_Width / 2, $i_Gui_Height + $iScroll_Height) ; ConsoleWrite("$aRet[0] = " & $aRet[0] & " $aRet[1] = " & $aRet[1] & @crlf) ;~ _GUIScrollBars_Init($h_GUI) ; phantom scrollbar + gap when no 2nd / 3rd param. _GUIScrollBars_Init($h_GUI, 1500) ; 2nd parameter changed to avoid phantom scrollbar + gap _GUIScrollBars_ShowScrollBar($h_GUI, $SB_VERT, False) _GUIScrollBars_ShowScrollBar($h_GUI, $SB_HORZ, True) _GUIScrollBars_SetScrollInfoPage($h_GUI, $SB_HORZ, $aRet[0]) _GUIScrollBars_SetScrollInfoMax($h_GUI, $SB_HORZ, $aRet[1] + 1) ; (+ 1 after test) EndFunc ; ==> _Create_Schrollbars ;======================================================== Func _Create_Keys() ; Create Keys For $row = 0 To $i_Rows - 1 For $col = 0 To $i_Cols - 1 $s_Key_Name = $row + 1 & "." & $col + 1 GUICtrlCreateLabel($s_Key_Name, _ ($col) * $i_Key_Width, _ ($row) * $i_Key_Height, _ $i_Key_Width, _ $i_Key_Height, _ BitOr($SS_CENTERIMAGE, $SS_CENTER, $SS_SUNKEN), _ $GUI_WS_EX_PARENTDRAG) GUICtrlSetTip(-1, _ $i_Key_Width & "w x " & _ $i_Key_Height & "h x " & _ $i_Rows & " rows") GUICtrlSetBkColor(-1, _ 0xFFFFFF) ; White GUICtrlSetFont(-1, _ Default, _ 900) ; Bold Next Next EndFunc ; ==> _Create_Keys ;======================================================== Func _Exit() ; Exit Exit EndFunc ; ==> _Exit ;======================================================== Func _Scrollbars_WM_HSCROLL($hWnd, $Msg, $wParam, $lParam) #forceref $Msg, $lParam Local $nScrollCode = BitAND($wParam, 0x0000FFFF) Local $iIndex = -1, $xChar, $xPos Local $Page, $Pos, $TrackPos For $x = 0 To UBound($__g_aSB_WindowInfo) - 1 If $__g_aSB_WindowInfo[$x][0] = $hWnd Then $iIndex = $x $xChar = $__g_aSB_WindowInfo[$iIndex][2] ExitLoop EndIf Next If $iIndex = -1 Then Return 0 Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_HORZ) $Page = DllStructGetData($tSCROLLINFO, "nPage") $xPos = DllStructGetData($tSCROLLINFO, "nPos") $Pos = $xPos $TrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos") Switch $nScrollCode Case $SB_LINELEFT DllStructSetData($tSCROLLINFO, "nPos", $Pos - 1) Case $SB_LINERIGHT DllStructSetData($tSCROLLINFO, "nPos", $Pos + 1) Case $SB_PAGELEFT DllStructSetData($tSCROLLINFO, "nPos", $Pos - $Page) Case $SB_PAGERIGHT DllStructSetData($tSCROLLINFO, "nPos", $Pos + $Page) Case $SB_THUMBTRACK DllStructSetData($tSCROLLINFO, "nPos", $TrackPos) EndSwitch DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS) _GUIScrollBars_SetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO) _GUIScrollBars_GetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO) $Pos = DllStructGetData($tSCROLLINFO, "nPos") If ($Pos <> $xPos) Then _GUIScrollBars_ScrollWindow($hWnd, $xChar * ($xPos - $Pos), 0) Return $GUI_RUNDEFMSG EndFunc ;==>_Scrollbars_WM_HSCROLL I'll try to add in a further post some tests results when both scrollbars are present. Edited April 17, 2022 by pixelsearch While... Wend loop more robust, taking care of Minimize button, Win-D, hide all taurus905 1 Link to comment Share on other sites More sharing options...
pixelsearch Posted April 17, 2022 Share Posted April 17, 2022 (edited) @taurus905 You'll find below the code that manages 2 scrollbars : expandcollapse popup; Resizing Gui with both Scrollbars Example.au3 #include <Array.au3> #include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WinAPISys.au3> #include "GUIScrollbars_Size.au3" Opt("MustDeclareVars", 1) HotKeySet("{PAUSE}", "_Increment") ; Increment HotKeySet("{ESC}", "_Exit") ; Exit ; Get 1 character height & width (before creating GUI, as it will be used to calculate controls size) Global $aCharSize = _GSB_Size_Text(GUICreate("")) ; M23's internal function in GUIScrollbars_Size.au3 GUIDelete() Global $iCharWidth = $aCharSize[0], $iCharHeight = $aCharSize[1] ; ConsoleWrite($iCharWidth & " " & $iCharHeight & @crlf) ; 7 & 16 on my PC ; _Create_Gui() ; Create Gui Global $h_Gui Global $i_Increment = 2 Global $i_Rows = 8 Global $i_Cols = 8 Global $i_Key_Width = $iCharWidth * 6 ; 42 on my PC (7 * 6) Global $i_Key_Height = $iCharHeight * 2 ; 32 on my PC (16 * 2) Global $i_Gui_Width Global $i_Gui_Height Global $nH_Pos, $nV_Pos, $iIncMini = 0 ; _Create_Schrollbars() ; Create Schrollbars Global $iScroll_Width = _WinAPI_GetSystemMetrics(2) ; Width of VScrollbar: SM_CXVSCROLL Global $iScroll_Height = _WinAPI_GetSystemMetrics(3) ; Height of HScrollbar: SM_CYHSCROLL ; ConsoleWrite($iScroll_Width & " " & $iScroll_Height & @crlf) ; 17 & 17 on my PC ; _Create_Keys() ; Create Keys Global $s_Key_Name MsgBox(262208, _ ; $MB_TOPMOST + $MB_ICONINFORMATION "Resizing Gui with both Scrollbars Example", _ "Use the 'Pause' key to increment Gui rows & cols" & @CRLF & @CRLF & _ "and the 'Escape' key to exit script." & @CRLF & @CRLF & _ "Scroll to end of Gui to see row & cols of keys" & @CRLF & _ "which shows consistent spacing.") GUIRegisterMsg($WM_HSCROLL, "_Scrollbars_WM_HSCROLL") GUIRegisterMsg($WM_VSCROLL, "_Scrollbars_WM_VSCROLL") _Increment() ; Increment While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch If BitAND(WinGetState($h_GUI), $WIN_STATE_MINIMIZED) Then ; Minimize button, Win-D, hide all $iIncMini += 1 If $iIncMini = 1 Then _GUIScrollBars_ShowScrollBar($h_GUI, $SB_BOTH, False) $nH_Pos = _GUIScrollBars_GetScrollPos($h_GUI, $SB_HORZ) $nV_Pos = _GUIScrollBars_GetScrollPos($h_GUI, $SB_VERT) _GUIScrollBars_SetScrollInfoPos($h_GUI, $SB_HORZ, 0) _GUIScrollBars_SetScrollInfoPos($h_GUI, $SB_VERT, 0) EndIf Else ; not Minimized If $iIncMini Then $iIncMini = 0 _GUIScrollBars_ShowScrollBar($h_GUI, $SB_BOTH, True) _GUIScrollBars_SetScrollInfoPos($h_GUI, $SB_HORZ, $nH_Pos) _GUIScrollBars_SetScrollInfoPos($h_GUI, $SB_VERT, $nV_Pos) EndIf EndIf WEnd ;============================================== Func _Increment() ; Increment GUIDelete($h_Gui) ; As the script deletes the GUI for each increment, no need to keep useless rows... ; ... in the GLOBAL array $__g_aSB_WindowInfo[][] declared in GuiScrollBars.au3 ; But it's also a good idea to keep the "useless" rows to check the changed values. ; Global $__g_aSB_WindowInfo[1][8] ; reset, exactly as found in GuiScrollBars.au3 ; _ArrayDisplay($__g_aSB_WindowInfo, "$__g_aSB_WindowInfo", Default, $ARRAYDISPLAY_NOROW) $i_Rows += $i_Increment $i_Gui_Height = $i_Key_Height * $i_Rows $i_Cols += $i_Increment $i_Gui_Width = $i_Key_Width * $i_Cols _Create_Gui() ; Create Gui _Create_Schrollbars() ; Create Schrollbars _Create_Keys() ; Create Keys GUISetState(@SW_SHOW, $h_Gui) EndFunc ; ==> _Increment ;======================================================== Func _Create_Gui() ; Create Gui $h_Gui = GUICreate("Resizing Gui", _ $i_Gui_Width / 2 + $iScroll_Width, _ $i_Gui_Height / 2 + $iScroll_Height, _ Default, _ Default, _ Default, _ $WS_EX_TOPMOST) EndFunc ; ==> _Create_Gui ;======================================================== Func _Create_Schrollbars() ; Create Schrollbars Local $aRet = _GUIScrollbars_Size($i_Gui_Width - $iScroll_Width / 2, $i_Gui_Height - $iScroll_Height / 2, _ $i_Gui_Width / 2 + $iScroll_Width, $i_Gui_Height / 2 + $iScroll_Height) ; ConsoleWrite("$aRet[0] = " & $aRet[0] & " $aRet[1] = " & $aRet[1] & _ ; " $aRet[2] = " & $aRet[2] & " $aRet[3] = " & $aRet[3] & @crlf) ; _GUIScrollBars_Init($h_GUI) ; phantom scrollbar + gap when no 2nd / 3rd param. _GUIScrollBars_Init($h_GUI, 1500, 100) ; 2nd & 3rd parameter to increase the values _GUIScrollBars_ShowScrollBar($h_GUI, $SB_HORZ, True) _GUIScrollBars_SetScrollInfoPage($h_GUI, $SB_HORZ, $aRet[0]) _GUIScrollBars_SetScrollInfoMax($h_GUI, $SB_HORZ, $aRet[1] + 1) ; (+ 1 after test) _GUIScrollBars_ShowScrollBar($h_GUI, $SB_VERT, True) _GUIScrollBars_SetScrollInfoPage($h_GUI, $SB_VERT, $aRet[2]) _GUIScrollBars_SetScrollInfoMax($h_GUI, $SB_VERT, $aRet[3]) EndFunc ; ==> _Create_Schrollbars ;======================================================== Func _Create_Keys() ; Create Keys For $row = 0 To $i_Rows - 1 For $col = 0 To $i_Cols - 1 $s_Key_Name = $row + 1 & "." & $col + 1 GUICtrlCreateLabel($s_Key_Name, _ ($col) * $i_Key_Width, _ ($row) * $i_Key_Height, _ $i_Key_Width, _ $i_Key_Height, _ BitOr($SS_CENTERIMAGE, $SS_CENTER, $SS_SUNKEN), _ $GUI_WS_EX_PARENTDRAG) GUICtrlSetTip(-1, _ $i_Key_Width & "w x " & _ $i_Key_Height & "h x " & _ $i_Rows & " rows") GUICtrlSetBkColor(-1, _ 0xFFFFFF) ; White GUICtrlSetFont(-1, _ Default, _ 900) ; Bold Next Next EndFunc ; ==> _Create_Keys ;======================================================== Func _Exit() ; Exit Exit EndFunc ; ==> _Exit ;======================================================== Func _Scrollbars_WM_HSCROLL($hWnd, $Msg, $wParam, $lParam) #forceref $Msg, $lParam Local $nScrollCode = BitAND($wParam, 0x0000FFFF) Local $iIndex = -1, $xChar, $xPos Local $Page, $Pos, $TrackPos For $x = 0 To UBound($__g_aSB_WindowInfo) - 1 If $__g_aSB_WindowInfo[$x][0] = $hWnd Then $iIndex = $x $xChar = $__g_aSB_WindowInfo[$iIndex][2] ExitLoop EndIf Next If $iIndex = -1 Then Return 0 Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_HORZ) $Page = DllStructGetData($tSCROLLINFO, "nPage") $xPos = DllStructGetData($tSCROLLINFO, "nPos") $Pos = $xPos $TrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos") Switch $nScrollCode Case $SB_LINELEFT DllStructSetData($tSCROLLINFO, "nPos", $Pos - 1) Case $SB_LINERIGHT DllStructSetData($tSCROLLINFO, "nPos", $Pos + 1) Case $SB_PAGELEFT DllStructSetData($tSCROLLINFO, "nPos", $Pos - $Page) Case $SB_PAGERIGHT DllStructSetData($tSCROLLINFO, "nPos", $Pos + $Page) Case $SB_THUMBTRACK DllStructSetData($tSCROLLINFO, "nPos", $TrackPos) EndSwitch DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS) _GUIScrollBars_SetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO) _GUIScrollBars_GetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO) $Pos = DllStructGetData($tSCROLLINFO, "nPos") If ($Pos <> $xPos) Then _GUIScrollBars_ScrollWindow($hWnd, $xChar * ($xPos - $Pos), 0) Return $GUI_RUNDEFMSG EndFunc ;==>_Scrollbars_WM_HSCROLL ;======================================================== Func _Scrollbars_WM_VSCROLL($hWnd, $Msg, $wParam, $lParam) #forceref $Msg, $wParam, $lParam Local $nScrollCode = BitAND($wParam, 0x0000FFFF) Local $iIndex = -1, $yChar, $yPos Local $Min, $Max, $Page, $Pos, $TrackPos For $x = 0 To UBound($__g_aSB_WindowInfo) - 1 If $__g_aSB_WindowInfo[$x][0] = $hWnd Then $iIndex = $x $yChar = $__g_aSB_WindowInfo[$iIndex][3] ExitLoop EndIf Next If $iIndex = -1 Then Return 0 Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT) $Min = DllStructGetData($tSCROLLINFO, "nMin") $Max = DllStructGetData($tSCROLLINFO, "nMax") $Page = DllStructGetData($tSCROLLINFO, "nPage") $yPos = DllStructGetData($tSCROLLINFO, "nPos") $Pos = $yPos $TrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos") Switch $nScrollCode Case $SB_TOP DllStructSetData($tSCROLLINFO, "nPos", $Min) Case $SB_BOTTOM DllStructSetData($tSCROLLINFO, "nPos", $Max) Case $SB_LINEUP DllStructSetData($tSCROLLINFO, "nPos", $Pos - 1) Case $SB_LINEDOWN DllStructSetData($tSCROLLINFO, "nPos", $Pos + 1) Case $SB_PAGEUP DllStructSetData($tSCROLLINFO, "nPos", $Pos - $Page) Case $SB_PAGEDOWN DllStructSetData($tSCROLLINFO, "nPos", $Pos + $Page) Case $SB_THUMBTRACK DllStructSetData($tSCROLLINFO, "nPos", $TrackPos) EndSwitch DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS) _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO) _GUIScrollBars_GetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO) $Pos = DllStructGetData($tSCROLLINFO, "nPos") If ($Pos <> $yPos) Then _GUIScrollBars_ScrollWindow($hWnd, 0, $yChar * ($yPos - $Pos)) $yPos = $Pos EndIf Return $GUI_RUNDEFMSG EndFunc ;==>_Scrollbars_WM_VSCROLL So this is the end of our "scrollbar journey". Thank you for this interesting challenge and to Melba23 for his continuous help. Have a great sunday Edited April 17, 2022 by pixelsearch While... Wend loop more robust, taking care of Minimize button, Win-D, hide all taurus905 1 Link to comment Share on other sites More sharing options...
pixelsearch Posted April 17, 2022 Share Posted April 17, 2022 Glad you liked the scripts, taurus905 In a few minutes, I'm gonna amend the While...Wend loop of 2 other scripts above (the vertical one and the horizontal one) to get a more robust loop, so all 3 scripts will behave correctly when the gui is restored after it was minimized using Win-D or "hide all" button from taskbar, as Melba23 indicated in this link taurus905 1 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now