What's the right way of implement this scroll bar function

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
songdg
Posts: 575
Joined: 04 Oct 2017, 20:04

What's the right way of implement this scroll bar function

22 Mar 2024, 22:39

What's the right way of implement this scroll bar function, I add a gui_text wnd.AddText(, "Please enter your name:") above, but it scroll with the gui_edits.

Code: Select all

#Requires AutoHotkey v2.0

WS_VSCROLL := 0x200000
WM_VSCROLL := 0x0115

SB_LINEUP   := 0
SB_LINEDOWN := 1

wnd := Gui(WS_VSCROLL)
wnd.OnEvent('Close', (*) => ExitApp())
wnd.OnEvent('Size', UpdateScrollBars.Bind(wnd))
wnd.AddText(, "Please enter your name:")
Loop 30 {
    wnd.AddText('xm y+15 w45 right', 'Line ' . A_Index)
    wnd.AddEdit('x+5 yp-3 w200', 'Text ' . A_Index)
}
wnd.AddText('xm y+0') ; <—— invisible text to push back the lower border
wnd.Show('h240')
OnMessage(WM_VSCROLL, OnScroll)

#HotIf WinActive(wnd)
WheelUp::
WheelDown:: {
    Loop 3 {
        SendMessage WM_VSCROLL, A_ThisHotkey ~= 'Up' ? SB_LINEUP : SB_LINEDOWN,,, wnd
    }
}

UpdateScrollBars(GuiObj, *) {
    ; SIF_RANGE = 0x1, SIF_PAGE = 0x2, SIF_DISABLENOSCROLL = 0x8, SB_HORZ = 0, SB_VERT = 1
    ; Calculate scrolling area.
    WinGetClientPos(, , &GuiW, &GuiH, GuiObj.Hwnd)
    L := T := 2147483647   ; Left, Top
    R := B := -2147483648  ; Right, Bottom
    For CtrlHwnd In WinGetControlsHwnd(GuiObj.Hwnd) {
        ControlGetPos(&CX, &CY, &CW, &CH, CtrlHwnd)
        L := Min(CX, L)
        T := Min(CY, T)
        R := Max(CX + CW, R)
        B := Max(CY + CH, B)
    }
    L -= 8, T -= 8
    R += 8, B += 8
    ScrW := R - L ; scroll width
    ScrH := B - T ; scroll height
    ; Initialize SCROLLINFO.
    SI := Buffer(28, 0)
    NumPut("UInt", 28, "UInt", 3, SI, 0) ; cbSize , fMask: SIF_RANGE | SIF_PAGE
    ; Update horizontal scroll bar.
    NumPut("Int", ScrW, "Int", GuiW, SI, 12) ; nMax , nPage
    DllCall("SetScrollInfo", "Ptr", GuiObj.Hwnd, "Int", 0, "Ptr", SI, "Int", 1) ; SB_HORZ
    ; Update vertical scroll bar.
    ; NumPut("UInt", SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL, SI, 4) ; fMask
    NumPut("Int", ScrH, "UInt", GuiH, SI, 12) ; nMax , nPage
    DllCall("SetScrollInfo", "Ptr", GuiObj.Hwnd, "Int", 1, "Ptr", SI, "Int", 1) ; SB_VERT
    ; Scroll if necessary
    X := (L < 0) && (R < GuiW) ? Min(Abs(L), GuiW - R) : 0
    Y := (T < 0) && (B < GuiH) ? Min(Abs(T), GuiH - B) : 0
    If (X || Y)
        DllCall("ScrollWindow", "Ptr", GuiObj.Hwnd, "Int", X, "Int", Y, "Ptr", 0, "Ptr", 0)
}
; ======================================================================================================================
OnWheel(W, L, M, H) {
    If !(HWND := WinExist()) || GuiCtrlFromHwnd(H)
        Return
    HT := DllCall("SendMessage", "Ptr", HWND, "UInt", 0x0084, "Ptr", 0, "Ptr", l) ; WM_NCHITTEST = 0x0084
    If (HT = 6) || (HT = 7) { ; HTHSCROLL = 6, HTVSCROLL = 7
        SB := (W & 0x80000000) ? 1 : 0 ; SB_LINEDOWN = 1, SB_LINEUP = 0
        SM := (HT = 6) ? 0x0114 : 0x0115 ;  WM_HSCROLL = 0x0114, WM_VSCROLL = 0x0115
        OnScroll(SB, 0, SM, HWND)
        Return 0
    }
}
; ======================================================================================================================
OnScroll(WP, LP, M, H) {
    Static SCROLL_STEP := 10
    Bar := (M = 0x0115) ; SB_HORZ=0, SB_VERT=1
    SI := Buffer(28, 0)
    NumPut("UInt", 28, "UInt", 0x17, SI) ; cbSize, fMask: SIF_ALL
    If !DllCall("GetScrollInfo", "Ptr", H, "Int", Bar, "Ptr", SI)
        Return
    RC := Buffer(16, 0)
    DllCall("GetClientRect", "Ptr", H, "Ptr", RC)
    NewPos := NumGet(SI, 20, "Int") ; nPos
    MinPos := NumGet(SI, 8, "Int") ; nMin
    MaxPos := NumGet(SI, 12, "Int") ; nMax
    Switch (WP & 0xFFFF) {
        Case 0: NewPos -= SCROLL_STEP ; SB_LINEUP
        Case 1: NewPos += SCROLL_STEP ; SB_LINEDOWN
        Case 2: NewPos -= NumGet(RC, 12, "Int") - SCROLL_STEP ; SB_PAGEUP
        Case 3: NewPos += NumGet(RC, 12, "Int") - SCROLL_STEP ; SB_PAGEDOWN
        Case 4, 5: NewPos := WP >> 16 ; SB_THUMBTRACK, SB_THUMBPOSITION
        Case 6: NewPos := MinPos ; SB_TOP
        Case 7: NewPos := MaxPos ; SB_BOTTOM
        Default: Return
    }
    MaxPos -= NumGet(SI, 16, "Int") ; nPage
    NewPos := Min(NewPos, MaxPos)
    NewPos := Max(MinPos, NewPos)
    OldPos := NumGet(SI, 20, "Int") ; nPos
    X := (Bar = 0) ? OldPos - NewPos : 0
    Y := (Bar = 1) ? OldPos - NewPos : 0
    If (X || Y) {
        ; Scroll contents of window and invalidate uncovered area.
        DllCall("ScrollWindow", "Ptr", H, "Int", X, "Int", Y, "Ptr", 0, "Ptr", 0)
        ; Update scroll bar.
        NumPut("Int", NewPos, SI, 20) ; nPos
        DllCall("SetScrollInfo", "ptr", H, "Int", Bar, "Ptr", SI, "Int", 1)
    }
}

Return to “Ask for Help (v2)”

Who is online

Users browsing this forum: alawsareps and 99 guests