;-- TIME_STAMP   2018-01-15 13:30:57   v 0.1

#cs
	http://www.autoit.de/index.php?page=Thread&postID=161092#post161092
	Functions:
	Scrollbar_Create($hWnd, $iBar, $iMax)
	Scrollbar_Scroll($hWnd, $iBar, $iPos)
	Scrollbar_GetPos($hWnd, $iBar)
	Scrollbar_Step($iStep, $hWnd=0, $iBar=0)
#CE

#Region    ;************ Includes ************
#include-once
#include <Array.au3>
#include <GuiScrollBars.au3>
#include <GuiconstantsEx.au3>
#include <WindowsConstants.au3>
;~ #include <ScrollBarConstants.au3>;~~~
#EndRegion ;************ Includes ************

Global $aSCROLL_AMOUNTS[1][3] = [[1]]

Func Scrollbar_Create($hWnd, $iBar, $iMin, $iMax, $iPageSize = Default)
	Local $iScrollH, $iScrollV, $aClientSize = WinGetClientSize($hWnd)

	If IsKeyword($iPageSize) Then $iPageSize = $iBar = $SB_HORZ ? Int($aClientSize[0] * 0.2) : $iBar = $SB_VERT ? Int($aClientSize[1] * 0.2) : 0
	If $iPageSize <= 0 Then Return 0

	ReDim $aSCROLL_AMOUNTS[UBound($aSCROLL_AMOUNTS) + 1][3]
	$aSCROLL_AMOUNTS[UBound($aSCROLL_AMOUNTS) - 1][0] = $hWnd
	$aSCROLL_AMOUNTS[UBound($aSCROLL_AMOUNTS) - 1][1] = $iBar
	$aSCROLL_AMOUNTS[UBound($aSCROLL_AMOUNTS) - 1][2] = $aSCROLL_AMOUNTS[0][0]

	$iMin = $iMin = -1 ? 0 : $iMin
	$iMax = $iMax <= $iMin ? $iMin +1 : $iMax

	_GUIScrollBars_EnableScrollBar($hWnd, $iBar)
	_GUIScrollBars_SetScrollRange($hWnd, $iBar, $iMin, $iMax)
	_GUIScrollBars_SetScrollInfoPage($hWnd, $iBar, $iPageSize)

	Switch $iBar	; $SB_HORZ = 0, $SB_VERT = 1, $SB_CTL = 2, $SB_BOTH = 3
		Case $SB_HORZ
			$iScrollH = GUIRegisterMsg($WM_HSCROLL, "WM_HSCROLL")
		Case $SB_VERT
			$iScrollV = GUIRegisterMsg($WM_VSCROLL, "WM_VSCROLL")
		Case $SB_CTL, $SB_BOTH
			$iScrollV = GUIRegisterMsg($WM_VSCROLL, "WM_VSCROLL")
			$iScrollH = GUIRegisterMsg($WM_HSCROLL, "WM_HSCROLL")
	EndSwitch

	Return SetExtended(BitOR($iScrollH, BitShift($iScrollV, -1)), $iMax)
EndFunc   ;==>Scrollbar_Create

Func Scrollbar_GetPos($hWnd, $iBar)
	Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $iBar)

	Return DllStructGetData($tSCROLLINFO, "nPos")
EndFunc   ;==>Scrollbar_GetPos

Func Scrollbar_Scroll($hWnd, $iBar, $iPos)
	Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $iBar)

	Local $iCurrentPos = DllStructGetData($tSCROLLINFO, "nPos")

	DllStructSetData($tSCROLLINFO, "nPos", $iPos)
	DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS)
	_GUIScrollBars_SetScrollInfo($hWnd, $iBar, $tSCROLLINFO)

	If $iBar = $SB_VERT Then

		Local $iRound = 0

		For $i = 1 To UBound($aSCROLL_AMOUNTS) - 1
			If $aSCROLL_AMOUNTS[$i][0] = $hWnd And $aSCROLL_AMOUNTS[$i][1] = $SB_VERT Then
				$iRound = $aSCROLL_AMOUNTS[$i][2]
			EndIf
		Next

		If Not $iRound Then Return 0

		_GUIScrollBars_ScrollWindow($hWnd, 0, Round(($iCurrentPos - $iPos) / $iRound) * $iRound)
	ElseIf $iBar = $SB_HORZ Then

		$iRound = 0

		For $i = 1 To UBound($aSCROLL_AMOUNTS) - 1
			If $aSCROLL_AMOUNTS[$i][0] = $hWnd And $aSCROLL_AMOUNTS[$i][1] = $SB_HORZ Then
				$iRound = $aSCROLL_AMOUNTS[$i][2]
			EndIf
		Next

		If Not $iRound Then Return 0

		_GUIScrollBars_ScrollWindow($hWnd, Round(($iCurrentPos - $iPos) / $iRound) * $iRound, 0)
	Else
		Return 0
	EndIf

	Return 1

EndFunc   ;==>Scrollbar_Scroll

Func Scrollbar_Step($iStep, $hWnd = 0, $iBar = 0)

	If Not $hWnd Or Not $iBar Then

		$aSCROLL_AMOUNTS[0][0] = $iStep
		Return 1

	EndIf

	Local $iID = 0

	For $i = 1 To UBound($aSCROLL_AMOUNTS) - 1
		If $aSCROLL_AMOUNTS[$i][0] = $hWnd And $aSCROLL_AMOUNTS[$i][1] = $iBar Then
			$iID = $i
			ExitLoop
		EndIf
	Next

	If Not $iID Then Return 0

	$aSCROLL_AMOUNTS[$iID][2] = $iStep

	Return 1

EndFunc   ;==>Scrollbar_Step

Func WM_VSCROLL($hWnd, $Msg, $wParam, $lParam)

	#forceref $Msg, $wParam, $lParam
	Local $nScrollCode = BitAND($wParam, 0x0000FFFF)
	Local $index = -1, $yChar, $yPos
	Local $Min, $Max, $Page, $Pos, $TrackPos
	; Get all the vertial scroll bar information
	Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_VERT)
	$Min = DllStructGetData($tSCROLLINFO, "nMin")
	$Max = DllStructGetData($tSCROLLINFO, "nMax")
	$Page = DllStructGetData($tSCROLLINFO, "nPage")
	; Save the position for comparison later on
	$yPos = DllStructGetData($tSCROLLINFO, "nPos")
	$Pos = $yPos
	$TrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos")

	Local $iRound = 0

	For $i = 1 To UBound($aSCROLL_AMOUNTS) - 1
		If $aSCROLL_AMOUNTS[$i][0] = $hWnd And $aSCROLL_AMOUNTS[$i][1] = $SB_VERT Then
			$iRound = $aSCROLL_AMOUNTS[$i][2]
		EndIf
	Next

	If Not $iRound Then Return $GUI_RUNDEFMSG

	Switch $nScrollCode
		Case $SB_TOP ; user clicked the HOME keyboard key
			DllStructSetData($tSCROLLINFO, "nPos", $Min)
		Case $SB_BOTTOM ; user clicked the END keyboard key
			DllStructSetData($tSCROLLINFO, "nPos", $Max)
		Case $SB_LINEUP ; user clicked the top arrow
			DllStructSetData($tSCROLLINFO, "nPos", $Pos - $iRound)
		Case $SB_LINEDOWN ; user clicked the bottom arrow
			DllStructSetData($tSCROLLINFO, "nPos", $Pos + $iRound)
		Case $SB_PAGEUP ; user clicked the scroll bar shaft above the scroll box
			DllStructSetData($tSCROLLINFO, "nPos", $Pos - $Page)
		Case $SB_PAGEDOWN ; user clicked the scroll bar shaft below the scroll box
			DllStructSetData($tSCROLLINFO, "nPos", $Pos + $Page)
		Case $SB_THUMBTRACK ; user dragged the scroll box
			DllStructSetData($tSCROLLINFO, "nPos", Round($TrackPos / $iRound) * $iRound)
	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
	$Pos = DllStructGetData($tSCROLLINFO, "nPos")


	If ($Pos <> $yPos) Then
		_GUIScrollBars_ScrollWindow($hWnd, 0, $yPos - $Pos)
	EndIf
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_VSCROLL

Func WM_HSCROLL($hWnd, $Msg, $wParam, $lParam)
	#forceref $Msg, $wParam, $lParam
	Local $nScrollCode = BitAND($wParam, 0x0000FFFF)
	Local $index = -1, $yChar, $yPos
	Local $Min, $Max, $Page, $Pos, $TrackPos
	; Get all the vertial scroll bar information
	Local $tSCROLLINFO = _GUIScrollBars_GetScrollInfoEx($hWnd, $SB_HORZ)
	$Min = DllStructGetData($tSCROLLINFO, "nMin")
	$Max = DllStructGetData($tSCROLLINFO, "nMax")
	$Page = DllStructGetData($tSCROLLINFO, "nPage")
	; Save the position for comparison later on
	$yPos = DllStructGetData($tSCROLLINFO, "nPos")
	$Pos = $yPos
	$TrackPos = DllStructGetData($tSCROLLINFO, "nTrackPos")

	Local $iRound = 0

	For $i = 1 To UBound($aSCROLL_AMOUNTS) - 1
		If $aSCROLL_AMOUNTS[$i][0] = $hWnd And $aSCROLL_AMOUNTS[$i][1] = $SB_HORZ Then
			$iRound = $aSCROLL_AMOUNTS[$i][2]
		EndIf
	Next

	If Not $iRound Then Return $GUI_RUNDEFMSG

	Switch $nScrollCode
		Case $SB_TOP ; user clicked the HOME keyboard key
			DllStructSetData($tSCROLLINFO, "nPos", $Min)
		Case $SB_BOTTOM ; user clicked the END keyboard key
			DllStructSetData($tSCROLLINFO, "nPos", $Max)
		Case $SB_LINEUP ; user clicked the top arrow
			DllStructSetData($tSCROLLINFO, "nPos", $Pos - $iRound)
		Case $SB_LINEDOWN ; user clicked the bottom arrow
			DllStructSetData($tSCROLLINFO, "nPos", $Pos + $iRound)
		Case $SB_PAGEUP ; user clicked the scroll bar shaft above the scroll box
			DllStructSetData($tSCROLLINFO, "nPos", $Pos - $Page)
		Case $SB_PAGEDOWN ; user clicked the scroll bar shaft below the scroll box
			DllStructSetData($tSCROLLINFO, "nPos", $Pos + $Page)
		Case $SB_THUMBTRACK ; user dragged the scroll box
			DllStructSetData($tSCROLLINFO, "nPos", Round($TrackPos / $iRound) * $iRound)
	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
	$Pos = DllStructGetData($tSCROLLINFO, "nPos")


	If ($Pos <> $yPos) Then
		_GUIScrollBars_ScrollWindow($hWnd, $yPos - $Pos, 0)
	EndIf
	Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_HSCROLL
