ILLBeBack

Two GUI Scrollbar Issues

17 posts in this topic

#1 ·  Posted (edited)

While playing with the example  in the help file for the UDF on “GUI Scroll Bars”, I’ve encountered 2 issues as follow:
 
1.  When the GUI is resizable (not done in the help file examples), resizing the GUI, after scrolling horizontally or vertically, causes all objects in the GUI to reposition within the GUI.
 
2.  The vertical Scroll Bar thumb size, and the maximum movement are incorrect.
 
 
 
Attached is a script that describes each step to reproduce the issues.  Use the buttons “Show Issue 1” and "Show Issue 2” to display the steps to follow for each issue.  Just perform those steps in the order given.  The script is based upon the example for UDF function _GUIScrollBars_Init, with modifications to the GUI section, but no modifications to functions WM_SIZE, WM_HSCROLL or WM_VSCROLL.
 
Same results in AutoIt v3.3.12.0 and 3.3.13.19 beta.
 
If I’m doing something wrong, or overlooking something, please advise.
 
ILLBeBack

Something_Wrong_Between_Docking_and_GUI_ScrollBars.au3

Edited by ILLBeBack

Share this post


Link to post
Share on other sites



The first issue is caused by the internal AutoIt sizing code, which is run after the WM_SIZE function. To prevent the internal AutoIt code from running, just return 0 in the bottom of WM_SIZE instead of $GUI_RUNDEFMSG.

An issue similar to the first issue shows up when the GUI is resized until one of the scroll bars disappears. This issue is more complicated and is handled in the WM_SIZE function in the code box.

The second issue is about setting the GUI height in _GUIScrollBars_Init. This should be done like this:

_GUIScrollBars_Init( $hGUI, -1, Round( $iMaxVScroll / $iCharY ) )
This is shown in the code box.

(I have tested on AutoIt 3.3.10 and had to replace $__g_aSB_WindowInfo with $aSB_WindowInfo. In the code box I have changed $aSB_WindowInfo back to $__g_aSB_WindowInfo.)

 

;; Something_Wrong_Between_Docking_and_GUI_ScrollBars.au3
;; Notes:
;;   1.  This script is based upon the example in the AutoIt help
;;         file for UDF function _GUIScrollBars_Init.  Similar effects
;;         can be observed using that example, although the child GUIs
;;         seem to behave correctly.
;;
;;   2.  Melba23's UDF, "Scrollbars Made Easy" also exhibits issue #1, but not #2.
;;         http://www.autoitscript.com/forum/topic/113723-scrollbars-made-easy-new-version-9-aug-14/

#include <GUIConstantsEx.au3>
#include <GuiScrollBars.au3>
#include <StructureConstants.au3>
#include <WindowsConstants.au3>

Global $hGUI, $iCharX, $iCharY

Example()

Func Example()
  Local $hGUIMsg

  Local $iMaxHScroll = 425
  Local $iMaxVScroll = 325

  Local $iGUIHeight = 300

  $hGUI = GUICreate("2 ScrollBar Issues", 400, $iGUIHeight, -1, -1, BitOR($WS_MINIMIZEBOX, $WS_CAPTION, $WS_POPUP, $WS_SYSMENU, $WS_SIZEBOX))
  GUISetBkColor(0x88AABB)

  $b0 = GUICtrlCreateButton("0,0 x 100,40", 0, 0, 100, 40)
  GUICtrlSetResizing(-1, $GUI_DOCKALL)

  $b1 = GUICtrlCreateButton("Show Issue 1", 120, 0, 100, 40)
  GUICtrlSetResizing(-1, $GUI_DOCKALL)

  $b2 = GUICtrlCreateButton("Show Issue 2", 230, 0, 100, 40)
  GUICtrlSetResizing(-1, $GUI_DOCKALL)

  Local $sIssue1 = _
      " 1.  Start the script." & @LF & _
      " 2.  Note the location of the leftmost button is 0,0." & @LF & _
      " 3.  Drag the horizontal scroll bar a little to the right." & @LF & _
      "      The left button scrolls off the left side as it should." & @LF & _
      "      So far, all is well." & @LF & _
      " 4.  Drag the bottom of the GUI up or down, noting that the button" & @LF & _
      "      moves completely into view (it should NOT do that!)." & @LF & _
      "      This note moves too, just like the button." & @LF & _
      " 5.  Drag the horizontal scroll bar all the way to the left." & @LF & _
      " 6.  Note the location of the leftmost button and this note. " & @LF & _
      "      They're NOT where they should be.  The leftmost button" & @LF & _
      "      should be at 0,0.  Click that button to get its position." & @LF & _
      " 7.  Drag the bottom of the GUI up or down, " & @LF & _
      "      and the button repositions correctly." & @LF & _
      " 8.  The same thing happens with the vertical scroll bar," & @LF & _
      "      and/or combinations of dragging the GUI borders." & @LF & _
      " 9.  This is NOT an issue if the window cannot be resized." & @LF & _
      "10.  This same issue occurs in Melba23's 'Scrollbars Made Easy' UDF."

  Local $sIssue2 = _
      " 1.  The height of the vertical scroll bar thumb, and its maximum " & @LF & _
      "      range are incorrect.  Since the height of the GUI is " & $iGUIHeight & ", and" & @LF & _
      "      function _GUIScrollBars_Init specifies the maximum vertical " & @LF & _
      "      value as " & $iMaxVScroll & ", the height of the thumb should be greater" & @LF & _
      "      then it is, and the movement should be very little, much like" & @LF & _
      "      the horizontal scroll bar."


  ;; Start with Issue 1 displayed in the label
  $l1 = GUICtrlCreateLabel($sIssue1, 60, 45, 400, 240)
  GUICtrlSetResizing(-1, $GUI_DOCKALL)
  GUICtrlSetBkColor(-1, 0xffffff)

  GUIRegisterMsg($WM_SIZE, "WM_SIZE")
  GUIRegisterMsg($WM_VSCROLL, "WM_VSCROLL")
  GUIRegisterMsg($WM_HSCROLL, "WM_HSCROLL")

  GUISetState(@SW_SHOW)

  ;; _GUIScrollBars_Init($hGUI)
  ;; _GUIScrollBars_Init($hGUI, $iMaxHScroll, $iMaxVScroll)

  _GUIScrollBars_Init($hGUI)
  $iCharX = $__g_aSB_WindowInfo[0][2]
  $iCharY = $__g_aSB_WindowInfo[0][3]
  $__g_aSB_WindowInfo[0][0] = 0

  _GUIScrollBars_Init( $hGUI, -1, Round( $iMaxVScroll / $iCharY ) )
  ; $iMaxHScroll is calculated properly by _GUIScrollBars_Init

  While 1
    $hGUIMsg = GUIGetMsg()

    Switch $hGUIMsg
      Case $GUI_EVENT_CLOSE
        ExitLoop

      Case $b0
        Local $a1 = ControlGetPos("2 ScrollBar Issues", "", $b0)
        MsgBox(4096, "Button Position", "The position of this button is " & $a1[0] & "," & $a1[1])

      Case $b1
        ;; Display issue 1
        GUICtrlSetData($l1, $sIssue1)

      Case $b2
        ;; Display issue 2
        GUICtrlSetData($l1, $sIssue2)

    EndSwitch
  WEnd

  Exit
EndFunc   ;==>Example


Func WM_SIZE($hWnd, $iMsg, $wParam, $lParam)
  ; Retrieve the dimensions of the client area.
  Local $iClientX = BitAND($lParam, 0x0000FFFF)
  Local $iClientY = BitShift($lParam, 16)
  $__g_aSB_WindowInfo[0][4] = $iClientX
  $__g_aSB_WindowInfo[0][5] = $iClientY

  ; Get vertical scroll bar info
  Local $vSCROLLINFO = _GUIScrollBars_GetScrollInfoEx( $hGUI, $SB_VERT )
  Local $vMax = DllStructGetData( $vSCROLLINFO, "nMax" )
  Local $vPage = Int( $iClientY / $iCharY )
  Local Static $vScrollBarHidden = ( $vPage > $vMax )

  ; Get horizontal scroll bar info
  Local $hSCROLLINFO = _GUIScrollBars_GetScrollInfoEx( $hGUI, $SB_HORZ )
  Local $hMax = DllStructGetData( $hSCROLLINFO, "nMax" )
  Local $hPage = Int( $iClientX / $iCharX )
  Local Static $hScrollBarHidden = ( $hPage > $hMax )

  ; Set vertical scroll bar info
  DllStructSetData($vSCROLLINFO, "nPage", $vPage)
  If $hScrollBarHidden <> ( $hPage > $hMax ) Then
    DllStructSetData($vSCROLLINFO, "nPos", 0)
    $hScrollBarHidden = ( $hPage > $hMax )
  EndIf
  _GUIScrollBars_SetScrollInfo($hGUI, $SB_VERT, $vSCROLLINFO)

  ; Set horizontal scroll bar info
  DllStructSetData($hSCROLLINFO, "nPage", $hPage )
  If $vScrollBarHidden <> ( $vPage > $vMax ) Then
    DllStructSetData($hSCROLLINFO, "nPos", 0)
    $vScrollBarHidden = ( $vPage > $vMax )
  EndIf
  _GUIScrollBars_SetScrollInfo($hGUI, $SB_HORZ, $hSCROLLINFO)

  ;Return $GUI_RUNDEFMSG
  Return 0
EndFunc   ;==>WM_SIZE

Func WM_HSCROLL($hWnd, $iMsg, $wParam, $lParam)
  #forceref $iMsg, $lParam
  Local $iScrollCode = BitAND($wParam, 0x0000FFFF)

  Local $iIndex = -1, $iCharX, $iPosX
  Local $iMin, $iMax, $iPage, $iPos, $iTrackPos

  For $x = 0 To UBound($__g_aSB_WindowInfo) - 1
    If $__g_aSB_WindowInfo[$x][0] = $hWnd Then
      $iIndex = $x
      $iCharX = $__g_aSB_WindowInfo[$iIndex][2]
      ExitLoop
    EndIf
  Next
  If $iIndex = -1 Then Return 0

  ; ; Get all the horizontal scroll bar information
  Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_HORZ)
  $iMin = DllStructGetData($tSCROLLINFO, "nMin")
  $iMax = DllStructGetData($tSCROLLINFO, "nMax")
  $iPage = DllStructGetData($tSCROLLINFO, "nPage")
  ; Save the position for comparison later on
  $iPosX = DllStructGetData($tSCROLLINFO, "nPos")
  $iPos = $iPosX
  $iTrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos")
  #forceref $iMin, $iMax
  Switch $iScrollCode

    Case $SB_LINELEFT ; user clicked left arrow
      DllStructSetData($tSCROLLINFO, "nPos", $iPos - 1)

    Case $SB_LINERIGHT ; user clicked right arrow
      DllStructSetData($tSCROLLINFO, "nPos", $iPos + 1)

    Case $SB_PAGELEFT ; user clicked the scroll bar shaft left of the scroll box
      DllStructSetData($tSCROLLINFO, "nPos", $iPos - $iPage)

    Case $SB_PAGERIGHT ; user clicked the scroll bar shaft right of the scroll box
      DllStructSetData($tSCROLLINFO, "nPos", $iPos + $iPage)

    Case $SB_THUMBTRACK ; user dragged the scroll box
      DllStructSetData($tSCROLLINFO, "nPos", $iTrackPos)
  EndSwitch

  ; // Set the position and then retrieve it.  Due to adjustments
  ; //   by Windows it may not be the same as the value set.

  DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS)
  _GUIScrollBars_SetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO)
  _GUIScrollBars_GetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO)
  ;// If the position has changed, scroll the window and update it
  $iPos = DllStructGetData($tSCROLLINFO, "nPos")
  If ($iPos <> $iPosX) Then _GUIScrollBars_ScrollWindow($hWnd, $iCharX * ($iPosX - $iPos), 0)
  Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_HSCROLL

Func WM_VSCROLL($hWnd, $iMsg, $wParam, $lParam)
  #forceref $iMsg, $wParam, $lParam
  Local $iScrollCode = BitAND($wParam, 0x0000FFFF)
  Local $iIndex = -1, $iCharY, $iPosY
  Local $iMin, $iMax, $iPage, $iPos, $iTrackPos

  For $x = 0 To UBound($__g_aSB_WindowInfo) - 1
    If $__g_aSB_WindowInfo[$x][0] = $hWnd Then
      $iIndex = $x
      $iCharY = $__g_aSB_WindowInfo[$iIndex][3]
      ExitLoop
    EndIf
  Next
  If $iIndex = -1 Then Return 0

  ; Get all the vertial scroll bar information
  Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT)
  $iMin = DllStructGetData($tSCROLLINFO, "nMin")
  $iMax = DllStructGetData($tSCROLLINFO, "nMax")
  $iPage = DllStructGetData($tSCROLLINFO, "nPage")
  ; Save the position for comparison later on
  $iPosY = DllStructGetData($tSCROLLINFO, "nPos")
  $iPos = $iPosY
  $iTrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos")

  Switch $iScrollCode
    Case $SB_TOP ; user clicked the HOME keyboard key
      DllStructSetData($tSCROLLINFO, "nPos", $iMin)

    Case $SB_BOTTOM ; user clicked the END keyboard key
      DllStructSetData($tSCROLLINFO, "nPos", $iMax)

    Case $SB_LINEUP ; user clicked the top arrow
      DllStructSetData($tSCROLLINFO, "nPos", $iPos - 1)

    Case $SB_LINEDOWN ; user clicked the bottom arrow
      DllStructSetData($tSCROLLINFO, "nPos", $iPos + 1)

    Case $SB_PAGEUP ; user clicked the scroll bar shaft above the scroll box
      DllStructSetData($tSCROLLINFO, "nPos", $iPos - $iPage)

    Case $SB_PAGEDOWN ; user clicked the scroll bar shaft below the scroll box
      DllStructSetData($tSCROLLINFO, "nPos", $iPos + $iPage)

    Case $SB_THUMBTRACK ; user dragged the scroll box
      DllStructSetData($tSCROLLINFO, "nPos", $iTrackPos)
  EndSwitch

  ; // Set the position and then retrieve it.  Due to adjustments
  ; //   by Windows it may not be the same as the value set.

  DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS)
  _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
  _GUIScrollBars_GetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
  ;// If the position has changed, scroll the window and update it
  $iPos = DllStructGetData($tSCROLLINFO, "nPos")

  If ($iPos <> $iPosY) Then
    _GUIScrollBars_ScrollWindow($hWnd, 0, $iCharY * ($iPosY - $iPos))
    $iPosY = $iPos
  EndIf

  Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_VSCROLL

Share this post


Link to post
Share on other sites
Thanks LarsJ.  Nice job coding around the issues!  I see you’ve completely rewritten Func WM_SIZE.  Hopefully this gets corrected in the AutoIt help file.  Do you have anything to do with getting that accomplished?  The same WM_SIZE coding also appears in the examples for functions _GUIScrollBars_SetScrollInfo and _GUIScrollBars_ScrollWindow.
 

Also, it appears that UDF function _GUIScrollBars_Init needs to be modified so that specifying the maximum vertical scroll value is straight forward, just like the horizontal value.  Having to call that function twice, with calculations between them to determine the values of $iCharX and $iCharY (as quoted below) is not very intuitive.

_GUIScrollBars_Init($hGUI)
$iCharX = $__g_aSB_WindowInfo[0][2]
$iCharY = $__g_aSB_WindowInfo[0][3]
$__g_aSB_WindowInfo[0][0] = 0
 
_GUIScrollBars_Init( $hGUI, -1, Round( $iMaxVScroll / $iCharY ) )

 

I've tested your coding in v3.3.12.0 and 3.3.13.19 beta, and both work perfectly.

Share this post


Link to post
Share on other sites

I have nothing to do with the help file or the UDF's. If you want the developers' attention to these issues, you can add a post to the "Help File/Documentation Issues" thread in the "Developer Chat" forum.

Share this post


Link to post
Share on other sites

I have nothing to do with the help file or the UDF's. If you want the developers' attention to these issues, you can add a post to the "Help File/Documentation Issues" thread in the "Developer Chat" forum.

Not a help file issue!!! But it did get my attention, as the user correctly followed the procedure of reporting issues related to AutoIt. Though it would be helpful if a concise re-producer could be created in future, actually I will leave the ticket open for someone to do that. Lets say if I see no re-uploaded code in the next two weeks then I will close the ticket.

_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 04/09/2015

Share this post


Link to post
Share on other sites

Not a help file issue!!! But it did get my attention, as the user correctly followed the procedure of reporting issues related to AutoIt. Though it would be helpful if a concise re-producer could be created in future, actually I will leave the ticket open for someone to do that. Lets say if I see no re-uploaded code in the next two weeks then I will close the ticket.

I'm sorry, but doesn't the attached script in post 1 reproduce the issue?

Share this post


Link to post
Share on other sites

I am not certain whether it can be classed as an AutoIt/UDF issue. It could be the nature of GUIs in Microsoft.


_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 04/09/2015

Share this post


Link to post
Share on other sites

I can see that when you scroll the horiz. scroll bar to the right, the GUI moves to the left, so the button is correctly placed when it says it's at some negative number. The client area is being moved, so the button's location is being moved with it, so when it moves off the screen the numbers go negative. Its current location is determined by the client area of the GUI currently, and when you scroll the client area, things move with it.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

I can see that when you scroll the horiz. scroll bar to the right, the GUI moves to the left, so the button is correctly placed when it says it's at some negative number. The client area is being moved, so the button's location is being moved with it, so when it moves off the screen the numbers go negative. Its current location is determined by the client area of the GUI currently, and when you scroll the client area, things move with it.

Yes, what you say is correct, but that’s not the issue.  The issue is if you Scroll, then Resize the window, then Scroll back, the controls have been repositioned away from their original positions.  Compare the code provided in post 2, by LarsJ, against the code I posted (which was based upon the code in the help file).

I’m only reviewing this post because I need Scrollbars again, and am looking to see if things have improved, as the help file still does not correctly handle resizing GUIs with Scrollbars.

I see that Melba23 has added Resizing support to GUIScrollBars_Ex (click HERE).  That appears to work.  However, while resizing the window, the GUI temporarily shifts to display the controls in the upper left corner, and I am looking for a way around that as I find it distracting.

Unfortunately, the bug report (ticket 2902) that I submitted 11 months ago was flagged 7 weeks ago as “Won’t Fix”, even though LarsJ fix was provided.

Share this post


Link to post
Share on other sites

ILLBeBack,

You have the LarsJ versions of the handlers, so what is stopping you using them in your script instead of the handlers in the Help file? If they work for you, use them - there is nothing "sacred" about a Windows message handler, it is just some AutoIt code.

M23


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

Spoiler

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

 

Share this post


Link to post
Share on other sites

ILLBeBack,

You have the LarsJ versions of the handlers, so what is stopping you using them in your script instead of the handlers in the Help file? If they work for you, use them - there is nothing "sacred" about a Windows message handler, it is just some AutoIt code.

M23

1.  Sometimes LarsJ’s fix doesn’t work, and controls do shift around.  Unfortunately, I’m unable to nail down what’s causing it.

2.  As I stated, I was looking to see if anything had improved since LarsJ’s fix.  That, of course, led me to your UDF.

I hope I didn’t offend you because of that one thing I don’t like about your Scrollbars UDF, as I like it very much other than that, and I appreciate your making it available to the community.  If I were smart enough, I would look into changing that behavior, but I’m not.

3.  I responded to KingBob’s post because it missed the point that the controls actually do shift.

Share this post


Link to post
Share on other sites

ILLBeBack,

Not offended at all. I will look into the difference between the 2 sets of handlers and see if I can get my UDF to respond to resizing as you wish.  But no promises as scrollbars are really complicated things to manage (which is why I wrote the UDF in the first place) and the 2 sets handle the scrollbars in a very different manner.

M23


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

Spoiler

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

 

Share this post


Link to post
Share on other sites

M23,

Thank you!  I fully appreciate how complex scrollbars are, unfortunately.

I'm looking at your code too, and just found where you are forcing the scrollbars back to their zero position (Kafu's technique, I think) in order to prevent the controls from shifting within the GUI after Resizing the GUI.  Now I'm trying to determine why that's necessary, and how to defeat it.  If I figure it out, I'll certainly let you know.


I've been able to reproduce the misplacement of controls when using LarsJ's fix.  Run his code, scroll the GUI all the way down, drag the bottom of the window down a little, scroll all the way back up, and see that the buttons are in the wrong place.

The same is true in the horizontal direction if scrolled all the way to the right.

If not scrolled to the horizontal or vertical limits, the misalignment does not occur.

ILLBeBack

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

The solution to the scenario in first post was to prevent the internal resizing code from running by returning 0 instead of $GUI_RUNDEFMSG.

The solution to the scenario in the post above is to run the internal code by returning $GUI_RUNDEFMSG.

To handle both situations, we can make the assumption that when the window is resized, the scroll boxes on both scroll bars are reset to zero positions (leftmost/topmost). Return $GUI_RUNDEFMSG to run the internal code.

Regards Lars.

;; Something_Wrong_Between_Docking_and_GUI_ScrollBars.au3
;; Notes:
;;   1.  This script is based upon the example in the AutoIt help
;;         file for UDF function _GUIScrollBars_Init.  Similar effects
;;         can be observed using that example, although the child GUIs
;;         seem to behave correctly.
;;
;;   2.  Melba23's UDF, "Scrollbars Made Easy" also exhibits issue #1, but not #2.
;;         http://www.autoitscript.com/forum/topic/113723-scrollbars-made-easy-new-version-9-aug-14/

#include <GUIConstantsEx.au3>
#include <GuiScrollBars.au3>
#include <StructureConstants.au3>
#include <WindowsConstants.au3>

Global $hGUI, $iCharX, $iCharY, $fScroll = False

Example()

Func Example()
  Local $hGUIMsg

  Local $iMaxHScroll = 425
  Local $iMaxVScroll = 325

  Local $iGUIHeight = 300

  $hGUI = GUICreate("2 ScrollBar Issues", 400, $iGUIHeight, -1, -1, BitOR($WS_MINIMIZEBOX, $WS_CAPTION, $WS_POPUP, $WS_SYSMENU, $WS_SIZEBOX))
  GUISetBkColor(0x88AABB)

  $b0 = GUICtrlCreateButton("0,0 x 100,40", 0, 0, 100, 40)
  GUICtrlSetResizing(-1, $GUI_DOCKALL)

  $b1 = GUICtrlCreateButton("Show Issue 1", 120, 0, 100, 40)
  GUICtrlSetResizing(-1, $GUI_DOCKALL)

  $b2 = GUICtrlCreateButton("Show Issue 2", 230, 0, 100, 40)
  GUICtrlSetResizing(-1, $GUI_DOCKALL)

  Local $sIssue1 = _
      " 1.  Start the script." & @LF & _
      " 2.  Note the location of the leftmost button is 0,0." & @LF & _
      " 3.  Drag the horizontal scroll bar a little to the right." & @LF & _
      "      The left button scrolls off the left side as it should." & @LF & _
      "      So far, all is well." & @LF & _
      " 4.  Drag the bottom of the GUI up or down, noting that the button" & @LF & _
      "      moves completely into view (it should NOT do that!)." & @LF & _
      "      This note moves too, just like the button." & @LF & _
      " 5.  Drag the horizontal scroll bar all the way to the left." & @LF & _
      " 6.  Note the location of the leftmost button and this note. " & @LF & _
      "      They're NOT where they should be.  The leftmost button" & @LF & _
      "      should be at 0,0.  Click that button to get its position." & @LF & _
      " 7.  Drag the bottom of the GUI up or down, " & @LF & _
      "      and the button repositions correctly." & @LF & _
      " 8.  The same thing happens with the vertical scroll bar," & @LF & _
      "      and/or combinations of dragging the GUI borders." & @LF & _
      " 9.  This is NOT an issue if the window cannot be resized." & @LF & _
      "10.  This same issue occurs in Melba23's 'Scrollbars Made Easy' UDF."

  Local $sIssue2 = _
      " 1.  The height of the vertical scroll bar thumb, and its maximum " & @LF & _
      "      range are incorrect.  Since the height of the GUI is " & $iGUIHeight & ", and" & @LF & _
      "      function _GUIScrollBars_Init specifies the maximum vertical " & @LF & _
      "      value as " & $iMaxVScroll & ", the height of the thumb should be greater" & @LF & _
      "      then it is, and the movement should be very little, much like" & @LF & _
      "      the horizontal scroll bar."


  ;; Start with Issue 1 displayed in the label
  $l1 = GUICtrlCreateLabel($sIssue1, 60, 45, 400, 240)
  GUICtrlSetResizing(-1, $GUI_DOCKALL)
  GUICtrlSetBkColor(-1, 0xffffff)

  GUIRegisterMsg($WM_SIZE, "WM_SIZE")
  GUIRegisterMsg($WM_VSCROLL, "WM_VSCROLL")
  GUIRegisterMsg($WM_HSCROLL, "WM_HSCROLL")
  GUIRegisterMsg($WM_ENTERSIZEMOVE, "WM_ENTERSIZEMOVE")

  GUISetState(@SW_SHOW)

  ;; _GUIScrollBars_Init($hGUI)
  ;; _GUIScrollBars_Init($hGUI, $iMaxHScroll, $iMaxVScroll)

  _GUIScrollBars_Init($hGUI)
  $iCharX = $__g_aSB_WindowInfo[0][2]
  $iCharY = $__g_aSB_WindowInfo[0][3]
  $__g_aSB_WindowInfo[0][0] = 0

  _GUIScrollBars_Init( $hGUI, -1, Round( $iMaxVScroll / $iCharY ) )
  ; $iMaxHScroll is calculated properly by _GUIScrollBars_Init

  While 1
    $hGUIMsg = GUIGetMsg()

    Switch $hGUIMsg
      Case $GUI_EVENT_CLOSE
        ExitLoop

      Case $b0
        Local $a1 = ControlGetPos("2 ScrollBar Issues", "", $b0)
        MsgBox(4096, "Button Position", "The position of this button is " & $a1[0] & "," & $a1[1])

      Case $b1
        ;; Display issue 1
        GUICtrlSetData($l1, $sIssue1)

      Case $b2
        ;; Display issue 2
        GUICtrlSetData($l1, $sIssue2)

    EndSwitch
  WEnd

  Exit
EndFunc   ;==>Example


Func WM_ENTERSIZEMOVE($hWnd, $iMsg, $wParam, $lParam)
  $fScroll = True
EndFunc

Func WM_SIZE($hWnd, $iMsg, $wParam, $lParam)
  If $fScroll Then
    $fScroll = False
    Local $tSCROLLINFO
    ; Reset position of scroll box on horizontal scroll bar
    $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_HORZ)
    DllStructSetData($tSCROLLINFO, "nPos", 0)
    DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS)
    _GUIScrollBars_SetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO)
    ; Reset position of scroll box on vertical scroll bar
    $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT)
    DllStructSetData($tSCROLLINFO, "nPos", 0)
    DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS)
    _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
  EndIf

  ; Retrieve the dimensions of the client area.
  Local $iClientX = BitAND($lParam, 0x0000FFFF)
  Local $iClientY = BitShift($lParam, 16)
  $__g_aSB_WindowInfo[0][4] = $iClientX
  $__g_aSB_WindowInfo[0][5] = $iClientY

  ; Get vertical scroll bar info
  Local $vSCROLLINFO = _GUIScrollBars_GetScrollInfoEx( $hGUI, $SB_VERT )
  Local $vMax = DllStructGetData( $vSCROLLINFO, "nMax" )
  Local $vPage = Int( $iClientY / $iCharY )
  Local Static $vScrollBarHidden = ( $vPage > $vMax )

  ; Get horizontal scroll bar info
  Local $hSCROLLINFO = _GUIScrollBars_GetScrollInfoEx( $hGUI, $SB_HORZ )
  Local $hMax = DllStructGetData( $hSCROLLINFO, "nMax" )
  Local $hPage = Int( $iClientX / $iCharX )
  Local Static $hScrollBarHidden = ( $hPage > $hMax )

  ; Set vertical scroll bar info
  DllStructSetData($vSCROLLINFO, "nPage", $vPage)
  If $hScrollBarHidden <> ( $hPage > $hMax ) Then
    DllStructSetData($vSCROLLINFO, "nPos", 0)
    $hScrollBarHidden = ( $hPage > $hMax )
  EndIf
  _GUIScrollBars_SetScrollInfo($hGUI, $SB_VERT, $vSCROLLINFO)

  ; Set horizontal scroll bar info
  DllStructSetData($hSCROLLINFO, "nPage", $hPage )
  If $vScrollBarHidden <> ( $vPage > $vMax ) Then
    DllStructSetData($hSCROLLINFO, "nPos", 0)
    $vScrollBarHidden = ( $vPage > $vMax )
  EndIf
  _GUIScrollBars_SetScrollInfo($hGUI, $SB_HORZ, $hSCROLLINFO)

  Return $GUI_RUNDEFMSG
  ;Return 0
EndFunc   ;==>WM_SIZE

Func WM_HSCROLL($hWnd, $iMsg, $wParam, $lParam)
  #forceref $iMsg, $lParam
  Local $iScrollCode = BitAND($wParam, 0x0000FFFF)

  Local $iIndex = -1, $iCharX, $iPosX
  Local $iMin, $iMax, $iPage, $iPos, $iTrackPos

  For $x = 0 To UBound($__g_aSB_WindowInfo) - 1
    If $__g_aSB_WindowInfo[$x][0] = $hWnd Then
      $iIndex = $x
      $iCharX = $__g_aSB_WindowInfo[$iIndex][2]
      ExitLoop
    EndIf
  Next
  If $iIndex = -1 Then Return 0

  ; ; Get all the horizontal scroll bar information
  Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_HORZ)
  $iMin = DllStructGetData($tSCROLLINFO, "nMin")
  $iMax = DllStructGetData($tSCROLLINFO, "nMax")
  $iPage = DllStructGetData($tSCROLLINFO, "nPage")
  ; Save the position for comparison later on
  $iPosX = DllStructGetData($tSCROLLINFO, "nPos")
  $iPos = $iPosX
  $iTrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos")
  #forceref $iMin, $iMax
  Switch $iScrollCode

    Case $SB_LINELEFT ; user clicked left arrow
      DllStructSetData($tSCROLLINFO, "nPos", $iPos - 1)

    Case $SB_LINERIGHT ; user clicked right arrow
      DllStructSetData($tSCROLLINFO, "nPos", $iPos + 1)

    Case $SB_PAGELEFT ; user clicked the scroll bar shaft left of the scroll box
      DllStructSetData($tSCROLLINFO, "nPos", $iPos - $iPage)

    Case $SB_PAGERIGHT ; user clicked the scroll bar shaft right of the scroll box
      DllStructSetData($tSCROLLINFO, "nPos", $iPos + $iPage)

    Case $SB_THUMBTRACK ; user dragged the scroll box
      DllStructSetData($tSCROLLINFO, "nPos", $iTrackPos)
  EndSwitch

  ; // Set the position and then retrieve it.  Due to adjustments
  ; //   by Windows it may not be the same as the value set.

  DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS)
  _GUIScrollBars_SetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO)
  _GUIScrollBars_GetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO)
  ;// If the position has changed, scroll the window and update it
  $iPos = DllStructGetData($tSCROLLINFO, "nPos")
  If ($iPos <> $iPosX) Then _GUIScrollBars_ScrollWindow($hWnd, $iCharX * ($iPosX - $iPos), 0)
  Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_HSCROLL

Func WM_VSCROLL($hWnd, $iMsg, $wParam, $lParam)
  #forceref $iMsg, $wParam, $lParam
  Local $iScrollCode = BitAND($wParam, 0x0000FFFF)
  Local $iIndex = -1, $iCharY, $iPosY
  Local $iMin, $iMax, $iPage, $iPos, $iTrackPos

  For $x = 0 To UBound($__g_aSB_WindowInfo) - 1
    If $__g_aSB_WindowInfo[$x][0] = $hWnd Then
      $iIndex = $x
      $iCharY = $__g_aSB_WindowInfo[$iIndex][3]
      ExitLoop
    EndIf
  Next
  If $iIndex = -1 Then Return 0

  ; Get all the vertial scroll bar information
  Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT)
  $iMin = DllStructGetData($tSCROLLINFO, "nMin")
  $iMax = DllStructGetData($tSCROLLINFO, "nMax")
  $iPage = DllStructGetData($tSCROLLINFO, "nPage")
  ; Save the position for comparison later on
  $iPosY = DllStructGetData($tSCROLLINFO, "nPos")
  $iPos = $iPosY
  $iTrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos")

  Switch $iScrollCode
    Case $SB_TOP ; user clicked the HOME keyboard key
      DllStructSetData($tSCROLLINFO, "nPos", $iMin)

    Case $SB_BOTTOM ; user clicked the END keyboard key
      DllStructSetData($tSCROLLINFO, "nPos", $iMax)

    Case $SB_LINEUP ; user clicked the top arrow
      DllStructSetData($tSCROLLINFO, "nPos", $iPos - 1)

    Case $SB_LINEDOWN ; user clicked the bottom arrow
      DllStructSetData($tSCROLLINFO, "nPos", $iPos + 1)

    Case $SB_PAGEUP ; user clicked the scroll bar shaft above the scroll box
      DllStructSetData($tSCROLLINFO, "nPos", $iPos - $iPage)

    Case $SB_PAGEDOWN ; user clicked the scroll bar shaft below the scroll box
      DllStructSetData($tSCROLLINFO, "nPos", $iPos + $iPage)

    Case $SB_THUMBTRACK ; user dragged the scroll box
      DllStructSetData($tSCROLLINFO, "nPos", $iTrackPos)
  EndSwitch

  ; // Set the position and then retrieve it.  Due to adjustments
  ; //   by Windows it may not be the same as the value set.

  DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS)
  _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
  _GUIScrollBars_GetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
  ;// If the position has changed, scroll the window and update it
  $iPos = DllStructGetData($tSCROLLINFO, "nPos")

  If ($iPos <> $iPosY) Then
    _GUIScrollBars_ScrollWindow($hWnd, 0, $iCharY * ($iPosY - $iPos))
    $iPosY = $iPos
  EndIf

  Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_VSCROLL

 

Edited by LarsJ

Share this post


Link to post
Share on other sites

LarsJ,

Thank you very much for taking the time to look into the latest issues.  I’ve run your new code, and indeed the repositioning of the controls no longer occurs.

However, as you’ve stated, in order to achieve these results, the GUI is scrolled to the upper left upon completion of the Resizing, which is not ideal behavior.  For example, if the GUI is scrolled to display a particular area of a GUI, that same area should be shown when the resizing is complete (plus or minus the area affected by the resize, depending upon which border was dragged).  In other words, how your code in post #2 worked (but without the relocation of the controls).

In the new version (your post 15), the GUI will have to be re-scrolled to the desired area after resizing.  To that end, I registered $WM_EXITSIZEMOVE, which restores both scrollbars to their original positions after the resizing is complete.  For this, I added code to func WM_ENTERSIZEMOVE to capture the scrollbar positions prior to resizing.  While this appears to be functioning properly when the Bottom and/or Right hand borders are dragged in any direction, that’s not the case when the Left and Top borders are dragged inward, as the scrollbars should move accordingly in those cases.  Any ideas how to resolve this issue would be appreciated.

Again, thank you very much for your efforts!

ILLBeBack

 

;; Something_Wrong_Between_Docking_and_GUI_ScrollBars.au3
;; Notes:
;;   1.  This script is based upon the example in the AutoIt help
;;         file for UDF function _GUIScrollBars_Init.  Similar effects
;;         can be observed using that example, although the child GUIs
;;         seem to behave correctly.
;;
;;   2.  Melba23's UDF, "Scrollbars Made Easy" also exhibits issue #1, but not #2.
;;         http://www.autoitscript.com/forum/topic/113723-scrollbars-made-easy-new-version-9-aug-14/

#include <GUIConstantsEx.au3>
#include <GuiScrollBars.au3>
#include <StructureConstants.au3>
#include <WindowsConstants.au3>

Global $hGUI, $iCharX, $iCharY, $fScroll = False
Global $GiHPos, $GiVPos

Example()

Func Example()
    Local $hGUIMsg

    Local $iMaxHScroll = 425
    Local $iMaxVScroll = 325

    Local $iGUIHeight = 300

    $hGUI = GUICreate("2 ScrollBar Issues", 400, $iGUIHeight, -1, -1, BitOR($WS_MINIMIZEBOX, $WS_CAPTION, $WS_POPUP, $WS_SYSMENU, $WS_SIZEBOX))
    GUISetBkColor(0x88AABB)

    $b0 = GUICtrlCreateButton("0,0 x 100,40", 0, 0, 100, 40)
    GUICtrlSetResizing(-1, $GUI_DOCKALL)

    $b1 = GUICtrlCreateButton("Show Issue 1", 120, 0, 100, 40)
    GUICtrlSetResizing(-1, $GUI_DOCKALL)

    $b2 = GUICtrlCreateButton("Show Issue 2", 230, 0, 100, 40)
    GUICtrlSetResizing(-1, $GUI_DOCKALL)

    Local $sIssue1 = _
            " 1.  Start the script." & @LF & _
            " 2.  Note the location of the leftmost button is 0,0." & @LF & _
            " 3.  Drag the horizontal scroll bar a little to the right." & @LF & _
            "      The left button scrolls off the left side as it should." & @LF & _
            "      So far, all is well." & @LF & _
            " 4.  Drag the bottom of the GUI up or down, noting that the button" & @LF & _
            "      moves completely into view (it should NOT do that!)." & @LF & _
            "      This note moves too, just like the button." & @LF & _
            " 5.  Drag the horizontal scroll bar all the way to the left." & @LF & _
            " 6.  Note the location of the leftmost button and this note. " & @LF & _
            "      They're NOT where they should be.  The leftmost button" & @LF & _
            "      should be at 0,0.  Click that button to get its position." & @LF & _
            " 7.  Drag the bottom of the GUI up or down, " & @LF & _
            "      and the button repositions correctly." & @LF & _
            " 8.  The same thing happens with the vertical scroll bar," & @LF & _
            "      and/or combinations of dragging the GUI borders." & @LF & _
            " 9.  This is NOT an issue if the window cannot be resized." & @LF & _
            "10.  This same issue occurs in Melba23's 'Scrollbars Made Easy' UDF."

    Local $sIssue2 = _
            " 1.  The height of the vertical scroll bar thumb, and its maximum " & @LF & _
            "      range are incorrect.  Since the height of the GUI is " & $iGUIHeight & ", and" & @LF & _
            "      function _GUIScrollBars_Init specifies the maximum vertical " & @LF & _
            "      value as " & $iMaxVScroll & ", the height of the thumb should be greater" & @LF & _
            "      then it is, and the movement should be very little, much like" & @LF & _
            "      the horizontal scroll bar."


    ;; Start with Issue 1 displayed in the label
    $l1 = GUICtrlCreateLabel($sIssue1, 60, 45, 400, 240)
    GUICtrlSetResizing(-1, $GUI_DOCKALL)
    GUICtrlSetBkColor(-1, 0xffffff)

    GUIRegisterMsg($WM_SIZE, "WM_SIZE")
    GUIRegisterMsg($WM_VSCROLL, "WM_VSCROLL")
    GUIRegisterMsg($WM_HSCROLL, "WM_HSCROLL")
    GUIRegisterMsg($WM_ENTERSIZEMOVE, "WM_ENTERSIZEMOVE")
    GUIRegisterMsg($WM_ExitSIZEMOVE, "WM_ExitSIZEMOVE")

    GUISetState(@SW_SHOW)

    ;; _GUIScrollBars_Init($hGUI)
    ;; _GUIScrollBars_Init($hGUI, $iMaxHScroll, $iMaxVScroll)

    _GUIScrollBars_Init($hGUI)
    $iCharX = $__g_aSB_WindowInfo[0][2]
    $iCharY = $__g_aSB_WindowInfo[0][3]
    $__g_aSB_WindowInfo[0][0] = 0

    _GUIScrollBars_Init($hGUI, -1, Round($iMaxVScroll / $iCharY))
    ; $iMaxHScroll is calculated properly by _GUIScrollBars_Init

    While 1
        $hGUIMsg = GUIGetMsg()

        Switch $hGUIMsg
            Case $GUI_EVENT_CLOSE
                ExitLoop

            Case $b0
                Local $a1 = ControlGetPos("2 ScrollBar Issues", "", $b0)
                MsgBox(4096, "Button Position", "The position of this button is " & $a1[0] & "," & $a1[1])

            Case $b1
                ;; Display issue 1
                GUICtrlSetData($l1, $sIssue1)

            Case $b2
                ;; Display issue 2
                GUICtrlSetData($l1, $sIssue2)

        EndSwitch
    WEnd

    Exit
EndFunc   ;==>Example


Func WM_ENTERSIZEMOVE($hWnd, $iMsg, $wParam, $lParam)
    $fScroll = True

    $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hGUI, $SB_VERT)
    $GiVPos = DllStructGetData($tSCROLLINFO, "nPos")

    $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hGUI, $SB_HORZ)
    $GiHPos = DllStructGetData($tSCROLLINFO, "nPos")
EndFunc


;; This function runs after the resizing is complete.
Func WM_EXITSIZEMOVE($hWnd, $iMsg, $wParam, $lParam)
    _GUIScrollBars_SetScrollInfoPos($hWnd, $SB_HORZ, $GiHPos)
    _GUIScrollBars_SetScrollInfoPos($hWnd, $SB_VERT, $GiVPos)
EndFunc


Func WM_SIZE($hWnd, $iMsg, $wParam, $lParam)
    If $fScroll Then
        $fScroll = False
        Local $tSCROLLINFO
        ; Reset position of scroll box on horizontal scroll bar
        $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_HORZ)
        DllStructSetData($tSCROLLINFO, "nPos", 0)
        DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS)
        _GUIScrollBars_SetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO)
        ; Reset position of scroll box on vertical scroll bar
        $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT)
        DllStructSetData($tSCROLLINFO, "nPos", 0)
        DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS)
        _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
    EndIf

    ; Retrieve the dimensions of the client area.
    Local $iClientX = BitAND($lParam, 0x0000FFFF)
    Local $iClientY = BitShift($lParam, 16)
    $__g_aSB_WindowInfo[0][4] = $iClientX
    $__g_aSB_WindowInfo[0][5] = $iClientY

    ; Get vertical scroll bar info
    Local $vSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hGUI, $SB_VERT)
    Local $vMax = DllStructGetData($vSCROLLINFO, "nMax")
    Local $vPage = Int($iClientY / $iCharY)
    Local Static $vScrollBarHidden = ($vPage > $vMax)

    ; Get horizontal scroll bar info
    Local $hSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hGUI, $SB_HORZ)
    Local $hMax = DllStructGetData($hSCROLLINFO, "nMax")
    Local $hPage = Int($iClientX / $iCharX)
    Local Static $hScrollBarHidden = ($hPage > $hMax)

    ; Set vertical scroll bar info
    DllStructSetData($vSCROLLINFO, "nPage", $vPage)
    If $hScrollBarHidden <> ($hPage > $hMax) Then
        DllStructSetData($vSCROLLINFO, "nPos", 0)
        $hScrollBarHidden = ($hPage > $hMax)
    EndIf
    _GUIScrollBars_SetScrollInfo($hGUI, $SB_VERT, $vSCROLLINFO)

    ; Set horizontal scroll bar info
    DllStructSetData($hSCROLLINFO, "nPage", $hPage)
    If $vScrollBarHidden <> ($vPage > $vMax) Then
        DllStructSetData($hSCROLLINFO, "nPos", 0)
        $vScrollBarHidden = ($vPage > $vMax)
    EndIf
    _GUIScrollBars_SetScrollInfo($hGUI, $SB_HORZ, $hSCROLLINFO)

    Return $GUI_RUNDEFMSG
    ;Return 0
EndFunc   ;==>WM_SIZE

Func WM_HSCROLL($hWnd, $iMsg, $wParam, $lParam)
    #forceref $iMsg, $lParam
    Local $iScrollCode = BitAND($wParam, 0x0000FFFF)

    Local $iIndex = -1, $iCharX, $iPosX
    Local $iMin, $iMax, $iPage, $iPos, $iTrackPos

    For $x = 0 To UBound($__g_aSB_WindowInfo) - 1
        If $__g_aSB_WindowInfo[$x][0] = $hWnd Then
            $iIndex = $x
            $iCharX = $__g_aSB_WindowInfo[$iIndex][2]
            ExitLoop
        EndIf
    Next
    If $iIndex = -1 Then Return 0

    ; ; Get all the horizontal scroll bar information
    Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_HORZ)
    $iMin = DllStructGetData($tSCROLLINFO, "nMin")
    $iMax = DllStructGetData($tSCROLLINFO, "nMax")
    $iPage = DllStructGetData($tSCROLLINFO, "nPage")
    ; Save the position for comparison later on
    $iPosX = DllStructGetData($tSCROLLINFO, "nPos")
    $iPos = $iPosX
    $iTrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos")
    #forceref $iMin, $iMax
    Switch $iScrollCode

        Case $SB_LINELEFT ; user clicked left arrow
            DllStructSetData($tSCROLLINFO, "nPos", $iPos - 1)

        Case $SB_LINERIGHT ; user clicked right arrow
            DllStructSetData($tSCROLLINFO, "nPos", $iPos + 1)

        Case $SB_PAGELEFT ; user clicked the scroll bar shaft left of the scroll box
            DllStructSetData($tSCROLLINFO, "nPos", $iPos - $iPage)

        Case $SB_PAGERIGHT ; user clicked the scroll bar shaft right of the scroll box
            DllStructSetData($tSCROLLINFO, "nPos", $iPos + $iPage)

        Case $SB_THUMBTRACK ; user dragged the scroll box
            DllStructSetData($tSCROLLINFO, "nPos", $iTrackPos)
    EndSwitch

    ; // Set the position and then retrieve it.  Due to adjustments
    ; //   by Windows it may not be the same as the value set.

    DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS)
    _GUIScrollBars_SetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO)
    _GUIScrollBars_GetScrollInfo($hWnd, $SB_HORZ, $tSCROLLINFO)
    ;// If the position has changed, scroll the window and update it
    $iPos = DllStructGetData($tSCROLLINFO, "nPos")
    If ($iPos <> $iPosX) Then _GUIScrollBars_ScrollWindow($hWnd, $iCharX * ($iPosX - $iPos), 0)
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_HSCROLL

Func WM_VSCROLL($hWnd, $iMsg, $wParam, $lParam)
    #forceref $iMsg, $wParam, $lParam
    Local $iScrollCode = BitAND($wParam, 0x0000FFFF)
    Local $iIndex = -1, $iCharY, $iPosY
    Local $iMin, $iMax, $iPage, $iPos, $iTrackPos

    For $x = 0 To UBound($__g_aSB_WindowInfo) - 1
        If $__g_aSB_WindowInfo[$x][0] = $hWnd Then
            $iIndex = $x
            $iCharY = $__g_aSB_WindowInfo[$iIndex][3]
            ExitLoop
        EndIf
    Next
    If $iIndex = -1 Then Return 0

    ; Get all the vertial scroll bar information
    Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT)
    $iMin = DllStructGetData($tSCROLLINFO, "nMin")
    $iMax = DllStructGetData($tSCROLLINFO, "nMax")
    $iPage = DllStructGetData($tSCROLLINFO, "nPage")
    ; Save the position for comparison later on
    $iPosY = DllStructGetData($tSCROLLINFO, "nPos")
    $iPos = $iPosY
    $iTrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos")

    Switch $iScrollCode
        Case $SB_TOP ; user clicked the HOME keyboard key
            DllStructSetData($tSCROLLINFO, "nPos", $iMin)

        Case $SB_BOTTOM ; user clicked the END keyboard key
            DllStructSetData($tSCROLLINFO, "nPos", $iMax)

        Case $SB_LINEUP ; user clicked the top arrow
            DllStructSetData($tSCROLLINFO, "nPos", $iPos - 1)

        Case $SB_LINEDOWN ; user clicked the bottom arrow
            DllStructSetData($tSCROLLINFO, "nPos", $iPos + 1)

        Case $SB_PAGEUP ; user clicked the scroll bar shaft above the scroll box
            DllStructSetData($tSCROLLINFO, "nPos", $iPos - $iPage)

        Case $SB_PAGEDOWN ; user clicked the scroll bar shaft below the scroll box
            DllStructSetData($tSCROLLINFO, "nPos", $iPos + $iPage)

        Case $SB_THUMBTRACK ; user dragged the scroll box
            DllStructSetData($tSCROLLINFO, "nPos", $iTrackPos)
    EndSwitch

    ; // Set the position and then retrieve it.  Due to adjustments
    ; //   by Windows it may not be the same as the value set.

    DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS)
    _GUIScrollBars_SetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
    _GUIScrollBars_GetScrollInfo($hWnd, $SB_VERT, $tSCROLLINFO)
    ;// If the position has changed, scroll the window and update it
    $iPos = DllStructGetData($tSCROLLINFO, "nPos")

    If ($iPos <> $iPosY) Then
        _GUIScrollBars_ScrollWindow($hWnd, 0, $iCharY * ($iPosY - $iPos))
        $iPosY = $iPos
    EndIf

    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_VSCROLL

 

 

Share this post


Link to post
Share on other sites

Please forget what I requested about dragging the Top and Left borders!  No program that I've found with scrollbars works that way!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

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

Create an account

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


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now