bladem2003 Posted Sunday at 08:22 PM Posted Sunday at 08:22 PM 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 Sunday at 10:01 PM Solution Posted Sunday at 10:01 PM (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 Monday at 01:06 AM by MattyD
bladem2003 Posted Monday at 05:42 AM Author Posted Monday at 05:42 AM (edited) Thanks, that's the solution. I've spent several hours trying without success. Edited Monday at 05:43 AM by bladem2003
MattyD Posted Monday at 06:07 AM Posted Monday at 06:07 AM 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