bladem2003 Posted September 21 Posted September 21 Good evening, I hope you are all well, Can someone help me to calculate the maximum horizontal scroll range? "_GUIScrollBars_SetScrollInfoMax($hGuiScroll, $SB_HORZ, $iXpos - 550)" Thanks in advance expandcollapse popup#include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #include <WinAPISysWin.au3> #include <GuiScrollBars.au3> #include <ScrollBarsConstants.au3> Local $iXpos = 10, $iButtonsCount = 20 $hGuiScroll = GUICreate("", 550, 70, -1, -1) GUISetBkColor(0x212121, $hGuiScroll) _GUIScrollBars_Init($hGuiScroll, 1000) _GUIScrollBars_ShowScrollBar($hGuiScroll, $SB_VERT, False) For $t = 1 To $iButtonsCount GUICtrlCreateButton($t, $iXpos, 5, 100, 28) $iXpos += 100 Next _GUIScrollBars_SetScrollInfoMax($hGuiScroll, $SB_HORZ, $iXpos - 550) GUISetState(@SW_SHOW, $hGuiScroll) GUIRegisterMsg($WM_NCHITTEST, "WM_NCHITTEST") GUIRegisterMsg($WM_HSCROLL, "__Scrollbars_WM_HSCROLL") While 1 Sleep(10) $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Then Exit WEnd ; #INTERNAL_USE_ONLY#============================================================================================================ ; Name...........: __Scrollbars_WM_HSCROLL ; Description ...: Handler for horizontal scrollbar ; Syntax ........: __Scrollbars_WM_HSCROLL($hWnd, $Msg, $wParam, $lParam) ; Return values .: None ; Author ........: Taken from AutoIt Help file ; Remarks .......: ; =============================================================================================================================== Func __Scrollbars_WM_HSCROLL($hWnd, $iMsg, $wParam, $lParam) #forceref $iMsg, $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 WM_NCHITTEST($hWnd, $iMsg, $wParam, $lParam) Local $iRet = _WinAPI_DefWindowProc($hWnd, $iMsg, $wParam, $lParam) Switch $iRet Case $HTVSCROLL Return $HTVSCROLL Case $HTHSCROLL Return $HTHSCROLL Case Else Return $HTCLIENT EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NCHITTEST
Solution MattyD Posted September 21 Solution Posted September 21 (edited) Hey mate, I could have this wrong, but from a bit of reading the distance of a scroll unit depends on line widths/heights. Presumably this is why _GuiScrollBars_Init() does something like this. $hGuiScroll = GUICreate("", 550, 70, -1, -1) Local $aCall = DllCall("user32.dll", "handle", "GetDC", "hwnd", $hGuiScroll) $hDC = $aCall[0] Local $tTEXTMETRIC = DllStructCreate($tagTEXTMETRIC) DllCall("gdi32.dll", "bool", "GetTextMetricsW", "handle", $hDC, "struct*", $tTEXTMETRIC) Local $iXAmount = DllStructGetData($tTEXTMETRIC, "tmAveCharWidth") Local $iYAmount = DllStructGetData($tTEXTMETRIC, "tmHeight") + DllStructGetData($tTEXTMETRIC, "tmExternalLeading") ConsoleWrite($iXAmount & @CRLF) ConsoleWrite($iYAmount & @CRLF) DllCall("user32.dll", "int", "ReleaseDC", "hwnd", $hGuiScroll, "handle", $hDC) I'm assuming these are the values for scrolling by "line", then a "page" is set to a multiple of this. According to MS The max scroll position is: MaxScrollPos = MaxRangeValue - (PageSize - 1) So if I have this right... $iClW = _WinAPI_GetClientWidth($hGuiScroll) $iFullW = $iButtonsCount * $iBtnW + 2 * $iMar $iPageW = _GUIScrollBars_GetScrollInfoPage($hGuiScroll, $SB_HORZ) $iMaxValRng = Int(($iFullW-$iClW)/$iXAmount) $iMaxScrollPos = $iMaxValRng + ($iPageW - 1) _GUIScrollBars_SetScrollInfoMax($hGuiScroll, $SB_HORZ, $iMaxScrollPos) _GUIScrollBars_SetScrollInfoMin($hGuiScroll, $SB_HORZ, 0) Edit: and here's something that is run-able expandcollapse popup#include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #include <WinAPISysWin.au3> #include <GuiScrollBars.au3> #include <ScrollBarsConstants.au3> $hGuiScroll = GUICreate("", 550, 70, -1, -1) Local $aCall = DllCall("user32.dll", "handle", "GetDC", "hwnd", $hGuiScroll) $hDC = $aCall[0] Local $tTEXTMETRIC = DllStructCreate($tagTEXTMETRIC) DllCall("gdi32.dll", "bool", "GetTextMetricsW", "handle", $hDC, "struct*", $tTEXTMETRIC) Local $iXAmount = DllStructGetData($tTEXTMETRIC, "tmAveCharWidth") Local $iYAmount = DllStructGetData($tTEXTMETRIC, "tmHeight") + DllStructGetData($tTEXTMETRIC, "tmExternalLeading") DllCall("user32.dll", "int", "ReleaseDC", "hwnd", $hGuiScroll, "handle", $hDC) GUISetBkColor(0x212121, $hGuiScroll) _GUIScrollBars_Init($hGuiScroll, 1000) _GUIScrollBars_ShowScrollBar($hGuiScroll, $SB_VERT, False) Local $iBtnW = 100, $iMar = 10 Local $iXpos = $iMar, $iButtonsCount = 20 For $t = 1 To $iButtonsCount GUICtrlCreateButton($t, $iXpos, 5, $iBtnW, 28) $iXpos += $iBtnW Next $iClW = _WinAPI_GetClientWidth($hGuiScroll) $iFullW = $iButtonsCount * $iBtnW + 2 * $iMar $iPageW = _GUIScrollBars_GetScrollInfoPage($hGuiScroll, $SB_HORZ) $iMaxValRng = Round(($iFullW-$iClW)/$iXAmount) $iMaxScrollPos = $iMaxValRng + ($iPageW - 1) ConsoleWrite(StringFormat("%20s: %-4d %20s: %-4d", "HScrollUnit", $iXAmount, "HPageSize", $iPageW) & @CRLF) ConsoleWrite(StringFormat("%20s: %-4d %20s: %-4d", "ClientWidth", $iClW, "FullFormWidth", $iFullW) & @CRLF) ConsoleWrite(StringFormat("%20s: %-4d %20s: %-4d", "MaxHRangeValue", $iMaxValRng, "MaxHScrollPos", $iMaxScrollPos) & @CRLF) _GUIScrollBars_SetScrollInfoMax($hGuiScroll, $SB_HORZ, $iMaxScrollPos) _GUIScrollBars_SetScrollInfoMin($hGuiScroll, $SB_HORZ, 0) GUISetState(@SW_SHOW, $hGuiScroll) GUIRegisterMsg($WM_NCHITTEST, "WM_NCHITTEST") GUIRegisterMsg($WM_HSCROLL, "__Scrollbars_WM_HSCROLL") While 1 Sleep(10) $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Then Exit WEnd ; #INTERNAL_USE_ONLY#============================================================================================================ ; Name...........: __Scrollbars_WM_HSCROLL ; Description ...: Handler for horizontal scrollbar ; Syntax ........: __Scrollbars_WM_HSCROLL($hWnd, $Msg, $wParam, $lParam) ; Return values .: None ; Author ........: Taken from AutoIt Help file ; Remarks .......: ; =============================================================================================================================== Func __Scrollbars_WM_HSCROLL($hWnd, $iMsg, $wParam, $lParam) #forceref $iMsg, $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 WM_NCHITTEST($hWnd, $iMsg, $wParam, $lParam) Local $iRet = _WinAPI_DefWindowProc($hWnd, $iMsg, $wParam, $lParam) Switch $iRet Case $HTVSCROLL Return $HTVSCROLL Case $HTHSCROLL Return $HTHSCROLL Case Else Return $HTCLIENT EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_NCHITTEST Edited September 22 by MattyD
bladem2003 Posted September 22 Author Posted September 22 (edited) Thanks, that's the solution. I've spent several hours trying without success. Edited September 22 by bladem2003
MattyD Posted September 22 Posted September 22 My pleasure Just a couple of extra tidbits I've found while having a play... Those base scroll unit values can be found in $__g_aSB_WindowInfo. So you don't want to re-calculate - first do a _GUIScrollBars_Init(), then just cycle through the array until you find your window handle. $__g_aSB_WindowInfo[$iIndex][0] = $hWnd $__g_aSB_WindowInfo[$iIndex][2] = $iHScrollUnit $__g_aSB_WindowInfo[$iIndex][3] = $iVScrollUnit The other thing I found was that the _WinAPI_GetClientWidth() and _WinAPI_GetClientHeight() values will change depending on if you're displaying a scroll bar. This is a good thing. If the vertical bar is showing, the overall width will shrink accordingly to accommodate whatever real estate was lost. But the take away is: make sure the the vertical/horizontal bars are in the correct visibility state before you take your measurements. Hope that makes sense! bladem2003 1
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