AutoHotkey Community

It is currently May 26th, 2012, 1:47 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 46 posts ]  Go to page Previous  1, 2, 3, 4  Next
Author Message
 Post subject:
PostPosted: December 3rd, 2008, 1:21 pm 
Lexikos wrote:
That adds the SIF_DISABLENOSCROLL flag, which causes the scroll bar to be disabled rather than hidden when it is not needed.


DataLife + Lexikos & ! This is really brilliant & smart and just what I needed. Quick question... I was trying to hook in this:

http://www.autohotkey.com/forum/viewtopic.php?t=21790

Do you know why it might not be registering with this control? It seems to work on notepad and other controls.., just not this one. Do you know why this might be happening? :?


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: December 9th, 2008, 12:00 pm 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7502
Location: Australia
It seems SetScrollInfo uses SB_THUMBPOSITION, which the script does not handle. Change
Code:
    else if action = 5 ; SB_THUMBTRACK
        new_pos := NumGet(si, 24, "int") ; nTrackPos
to
Code:
    else if (action = 5 || action = 4) ; SB_THUMBTRACK || SB_THUMBPOSITION
        new_pos := wParam>>16
The "si" structure contains the old position; the new position must be retrieved from wParam. I've updated my post on the first page.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 9th, 2008, 10:34 pm 
Offline

Joined: May 4th, 2007, 7:59 pm
Posts: 102
Hey that is really great! :)

There was one other quandary... that concept you made for a hotkey to move the scrollbar, ... that concept does not seem to work here off the bat (though the smooth scrolling works via normal mouse grab & move... just not the hotkey function below)

It was from here: http://www.autohotkey.com/forum/post-153675.html#153675

I looked it over carefully, but didn't see anything obvious, liken to the changes needed for this GUI to work with smooth momentum scrolling normally :D Can you see what is wrong? :?

EDIT 1: If I am not mistaken, it looks like it is the HWND that is not being picked up somehow when the Kicktoolbar function is being called. I tried a few things, but it seems to have its own ID (as Static1), and generates a different HWND address when using the Kicktoolbar function, which is strange

EDIT 2: BUT HEY, to my surprise (!) when I combined the two scripts together, the thing malfunctions (the insides go wacky). When I ran them separately, it worked just fine (minus the hotkey(s) which are assigned to SCROLLMOMEMTUM, ... but I don't know how this could be conflicting :D

Code:

#NoEnv

; CONFIGURATION
;

UPDATE_RATE = 10 ; milliseconds
SENSITIVITY = 0.5
INERTIA = 0.95

;
; WIN32 DEFINES
;
; SetWinEventHook Flags
WINEVENT_OUTOFCONTEXT       = 0x0000
; Events
EVENT_SYSTEM_SCROLLINGSTART = 0x0012
EVENT_SYSTEM_SCROLLINGEND   = 0x0013
; Scrollbar Constants
SB_HORZ = 0
SB_VERT = 1

GuiClose:
ExitApp

UpdateScrollBars(GuiNum, GuiWidth, GuiHeight)
{

  Global THIS_IS_SCROLL_TOKEN_LIT

    static SIF_RANGE=0x1, SIF_PAGE=0x2, SIF_DISABLENOSCROLL=0x8, SB_HORZ=0, SB_VERT=1
   
    Gui, %GuiNum%:Default
    Gui, +LastFound
   


    ; Calculate scrolling area.
    Left := Top := 9999
    Right := Bottom := 0
    WinGet, ControlList, ControlList
    Loop, Parse, ControlList, `n
    {
        GuiControlGet, c, Pos, %A_LoopField%
        if (cX < Left)
            Left := cX
        if (cY < Top)
            Top := cY
        if (cX + cW > Right)
            Right := cX + cW
        if (cY + cH > Bottom)
            Bottom := cY + cH
    }
    Left -= 8
    Top -= 8
    Right += 8
    Bottom += 8
    ScrollWidth := Right-Left
    ScrollHeight := Bottom-Top
   
    ; Initialize SCROLLINFO.
    VarSetCapacity(si, 28, 0)
    NumPut(28, si) ; cbSize
    NumPut(SIF_RANGE | SIF_PAGE, si, 4) ; fMask
   
    ; Update horizontal scroll bar.
    NumPut(ScrollWidth, si, 12) ; nMax
    NumPut(GuiWidth, si, 16) ; nPage
    DllCall("SetScrollInfo", "uint", WinExist(), "uint", SB_HORZ, "uint", &si, "int", 1)
   
THIS_IS_SCROLL_TOKEN_LIT:=WinExist()


    ; Update vertical scroll bar.
;     NumPut(SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL, si, 4) ; fMask
    NumPut(ScrollHeight, si, 12) ; nMax
    NumPut(GuiHeight, si, 16) ; nPage
    DllCall("SetScrollInfo", "uint", WinExist(), "uint", SB_VERT, "uint", &si, "int", 1)
   
    if (Left < 0 && Right < GuiWidth)
        x := Abs(Left) > GuiWidth-Right ? GuiWidth-Right : Abs(Left)
    if (Top < 0 && Bottom < GuiHeight)
        y := Abs(Top) > GuiHeight-Bottom ? GuiHeight-Bottom : Abs(Top)
    if (x || y)
        DllCall("ScrollWindow", "uint", WinExist(), "int", x, "int", y, "uint", 0, "uint", 0)
}

OnScroll(wParam, lParam, msg, hwnd)
{
    static SIF_ALL=0x17, SCROLL_STEP=10
   
    bar := msg=0x115 ; SB_HORZ=0, SB_VERT=1
   
    VarSetCapacity(si, 28, 0)
    NumPut(28, si) ; cbSize
    NumPut(SIF_ALL, si, 4) ; fMask
    if !DllCall("GetScrollInfo", "uint", hwnd, "int", bar, "uint", &si)
        return
   
    VarSetCapacity(rect, 16)
    DllCall("GetClientRect", "uint", hwnd, "uint", &rect)
   
    new_pos := NumGet(si, 20) ; nPos
   
    action := wParam & 0xFFFF
    if action = 0 ; SB_LINEUP
        new_pos -= SCROLL_STEP
    else if action = 1 ; SB_LINEDOWN
        new_pos += SCROLL_STEP
    else if action = 2 ; SB_PAGEUP
        new_pos -= NumGet(rect, 12, "int") - SCROLL_STEP
    else if action = 3 ; SB_PAGEDOWN
        new_pos += NumGet(rect, 12, "int") - SCROLL_STEP
    else if (action = 5 || action = 4) ; SB_THUMBTRACK
        new_pos := wParam>>16 ; nTrackPos
    else if action = 6 ; SB_TOP
        new_pos := NumGet(si, 8, "int") ; nMin
    else if action = 7 ; SB_BOTTOM
        new_pos := NumGet(si, 12, "int") ; nMax
    else
        return
   
    min := NumGet(si, 8, "int") ; nMin
    max := NumGet(si, 12, "int") - NumGet(si, 16) ; nMax-nPage
    new_pos := new_pos > max ? max : new_pos
    new_pos := new_pos < min ? min : new_pos
   
    old_pos := NumGet(si, 20, "int") ; nPos
   
    x := y := 0
    if bar = 0 ; SB_HORZ
        x := old_pos-new_pos
    else
        y := old_pos-new_pos
    ; Scroll contents of window and invalidate uncovered area.
    DllCall("ScrollWindow", "uint", hwnd, "int", x, "int", y, "uint", 0, "uint", 0)
   
    ; Update scroll bar.
    NumPut(new_pos, si, 20, "int") ; nPos
    DllCall("SetScrollInfo", "uint", hwnd, "int", bar, "uint", &si, "int", 1)
}



WheelUp::
WheelDown::
+WheelUp::
+WheelDown::
Up::
Down::
    ; SB_LINEDOWN=1, SB_LINEUP=0, WM_HSCROLL=0x114, WM_VSCROLL=0x115
    OnScroll(InStr(A_ThisHotkey,"Down") ? 1 : 0, 0, GetKeyState("Shift") ? 0x114 : 0x115, WinExist())
return



CleanupAndExit:
    ; May not be necessary; but for good measure...
    if hScrollHook
        DllCall("UnhookWinEvent", "uint", hScrollHook)
ExitApp


ContinueScroll:
    Scroll_Speed *= INERTIA
   
    ; Continue until
    ;   the scroll bar slows to a stop,
    ;   the window is closed,
    ;   or something else moves the scroll bar.

    if (Abs(Scroll_Speed)>0.01
        && GetAbstractScrollInfo(Scroll_Container, Scroll_Type, Scroll_Pos_Int)
        && Scroll_Pos_Int = Last_Pos)
    {
        ; Apply momentum.
        Scroll_Pos += Scroll_Speed
        ; Check if it hit the end.
        if (Scroll_Pos <  Scroll_Min)
            Scroll_Pos := Scroll_Min
        if (Scroll_Pos >  Scroll_Max)
            Scroll_Pos := Scroll_Max
        ; If it has come to a stop, stop the timer.
        if (Scroll_Pos = Last_Pos) {
            SetTimer, ContinueScroll, Off
            return
        }
        ; Move scroll bar.
        if SetAbstractScrollPos(Scroll_Container, Scroll_Type, Round(Scroll_Pos))
        {   ; Update position (to detect if something else moves the bar.)
            GetAbstractScrollInfo(Scroll_Container, Scroll_Type, Last_Pos)
            return
        }
    }
    SetTimer, ContinueScroll, Off
    gosub ReleaseScrollContainerIfNecessary
return

TrackScrollBar:
    ; Update scroll position.
    if GetAbstractScrollInfo(Scroll_Container, Scroll_Type, Scroll_Pos)
    {   ; Recalculate velocity.
        Scroll_Speed := Scroll_Speed*SpeedA + (Scroll_Pos-Last_Pos)*SENSITIVITY
        Last_Pos := Scroll_Pos
    }
    else
    {   ; Error: maybe the window closed?
        SetTimer, TrackScrollBar, Off
        gosub ReleaseScrollContainerIfNecessary
    }
return


ReleaseScrollContainerIfNecessary:
    if Scroll_Type in scrollbarHThumb,scrollbarVThumb
        COM_Release(Scroll_Container)
    Scroll_Container = 0
return
 

[Moderator's note: Edited code to enable word-wrap in several places.]


Last edited by FireGirl on December 12th, 2008, 10:47 pm, edited 3 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 10th, 2008, 7:13 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7502
Location: Australia
FireGirl wrote:
Can you see what is wrong? :?
The script is designed to scroll the active control, not the window itself. If there was enough text in the active edit field to enable the scrollbar, it would scroll.
Quote:
BUT HEY, to my surprise (!) when I combined the two scripts together, the thing malfunctions (the insides go wacky).
Where's ScrollInit()???

Btw, Sean has in the past objected to verbatim inclusion of COM.ahk in another script. I would prefer you did not post it here, if only because the code doesn't wrap well (it forces the page to be wider than the browser.) If it is a standard copy of COM.ahk, there is no need to repost it here (and no need to include it directly in your script, but that is less important.)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 10th, 2008, 3:10 pm 
Offline

Joined: May 4th, 2007, 7:59 pm
Posts: 102
Lexikos wrote:
FireGirl wrote:
Can you see what is wrong? :?
The script is designed to scroll the active control, not the window itself. If there was enough text in the active edit field to enable the scrollbar, it would scroll.


The example GUI included in the last code post actually runs off the bottom of the GUI (is taller), and no matter what you put in there, when you try to throw the scrollbar, it just slips and slides the contents? :? But, if you try as a test to separate the GUI from Scrollmomemtum, you can see what I mean - it works great then!

Lexikos wrote:
Btw, Sean has in the past objected to verbatim inclusion of COM.ahk in another script. I would prefer you did not post it here, if only because the code doesn't wrap well (it forces the page to be wider than the browser.) If it is a standard copy of COM.ahk, there is no need to repost it here (and no need to include it directly in your script, but that is less important.)


Ah, gotcha~! No worries :)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 10th, 2008, 3:57 pm 
Offline

Joined: May 4th, 2007, 7:59 pm
Posts: 102
I guess one way to better visualize what I see is, combine Scrollable Gui + ScrollMomentum, and change this:

Code:

#NoEnv

OnMessage(0x115, "OnScroll") ; WM_VSCROLL
OnMessage(0x114, "OnScroll") ; WM_HSCROLL

Gui, +Resize +0x300000 ; WS_VSCROLL | WS_HSCROLL

Loop 8
    Gui, Add, Edit, R5 W400, Edit %A_Index%
Gui, Add, Button,, Do absolutely nothing
Gui, Show, W200 H200

Gui, +LastFound
GroupAdd, MyGui, % "ahk_id " . WinExist()

return



to this

Code:

#NoEnv

OnMessage(0x115, "OnScroll") ; WM_VSCROLL
OnMessage(0x114, "OnScroll") ; WM_HSCROLL

Gui, +Resize +0x300000 ; WS_VSCROLL | WS_HSCROLL

Loop 8
Gui, Add, Button,, Do absolutely nothing

Gui, Show, W200 H200

Gui, +LastFound
GroupAdd, MyGui, % "ahk_id " . WinExist()

return



;removed
;Gui, Add, Edit, R5 W400, Edit %A_Index%





btw, ScrollInit() was actually a function from initial iteration of Scrollable Gui by ahklerner ;) :D

The inside edit boxes actually do scroll smoothly when placed in there, it is the outer GUI that malfunctions, unless you run it separately from ScrollMomentum :?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 10th, 2008, 10:20 pm 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7502
Location: Australia
FireGirl wrote:
it is the outer GUI that malfunctions, unless you run it separately from ScrollMomentum :?
What do you mean, "the outer GUI"? After taking a closer look at your script, it seems to function as it should. The Edit fields are narrower and you've removed the button and one edit field.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 11th, 2008, 12:44 am 
Offline

Joined: May 4th, 2007, 7:59 pm
Posts: 102
But, try placing a bunch of buttons, or anything other than those edit controls so scrollbars are created in this GUI design, and you'll see what I mean. When you try to scroll around it graphically messes up (in both XP and Vista). But only if the scripts are combined together. Seperately it actually works! :)

I am so sorry, to clairfy I meant the GUI itself, those scrollbars :)... outer was a bit misleading, I mean the actual GUI scrollbars. :)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 11th, 2008, 8:59 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7502
Location: Australia
FireGirl wrote:
when you try to throw the scrollbar, it just slips and slides the contents
Either I missed that bit, or it worked for me the first time around. In any case, I see what you mean now and I'll look into it.

However, I must question your motivation for combining the scripts. The momentum is applied system-wide, but the GUI part of the script must also be running. There may be better ways to apply momentum only to the GUI. Although hooks may still be required for the edit fields, they could be restricted to the current thread (i.e. the script.)

FYI, I got what you meant by "outer GUI", but wasn't sure since the GUI seemed to be working for me. :)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 11th, 2008, 2:57 pm 
Offline

Joined: May 4th, 2007, 7:59 pm
Posts: 102
I guess one way to better visualize what I see is, combine Scrollable Gui + ScrollMomentum, and change this:

Code:

#NoEnv

OnMessage(0x115, "OnScroll") ; WM_VSCROLL
OnMessage(0x114, "OnScroll") ; WM_HSCROLL

Gui, +Resize +0x300000 ; WS_VSCROLL | WS_HSCROLL

Loop 8
    Gui, Add, Edit, R5 W400, Edit %A_Index%
Gui, Add, Button,, Do absolutely nothing
Gui, Show, W200 H200

Gui, +LastFound
GroupAdd, MyGui, % "ahk_id " . WinExist()

return



to this

Code:

#NoEnv

OnMessage(0x115, "OnScroll") ; WM_VSCROLL
OnMessage(0x114, "OnScroll") ; WM_HSCROLL

Gui, +Resize +0x300000 ; WS_VSCROLL | WS_HSCROLL

Loop 8
Gui, Add, Button,, Do absolutely nothing

Gui, Show, W200 H200

Gui, +LastFound
GroupAdd, MyGui, % "ahk_id " . WinExist()

return



;removed
;Gui, Add, Edit, R5 W400, Edit %A_Index%





btw, ScrollInit() was actually a function from initial iteration of Scrollable Gui by ahklerner ;) :D

The inside edit boxes actually do scroll smoothly when placed in there, it is the outer GUI that malfunctions, unless you run it separately from ScrollMomentum :?


Last edited by FireGirl on December 12th, 2008, 10:42 pm, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 11th, 2008, 11:21 pm 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7502
Location: Australia
FireGirl wrote:
1) Capability to combine these two scripts together so they don't conflict
Remove the following section from SetScrollPos()
Code:
    VarSetCapacity(si, 28, 0) ; SCROLLINFO si
    NumPut(28  , si,  0)    ; si.cbSize := sizeof(SCROLLINFO)
    NumPut(0x4 , si,  4)    ; si.fMask := SIF_POS
    NumPut(nPos, si, 20)    ; si.nPos := nPos
 
    ; Use SetScrollInfo first because it supports 32-bit positions.
    ; If an application supports positions < 0 or > 65535, it most likely
    ; ignores WM_#SCROLL's wParam and uses GetScrollPos or GetScrollInfo
    ; to get the actual scroll position.
    DllCall("SetScrollInfo", "uint", hwnd, "int", fnBar, "uint", &si, "int", 0)
When the script receives the scroll message, it uses GetScrollInfo to determine the old position in order to calculate the distance to move all controls. If SetScrollInfo is used immediately before sending the message, the perceived "old" position is actually the new position, so the script does not move the controls. This only happens if it is called from within the same script. SetScrollInfo does not seem to be necessary for the few applications I tested on.
Quote:
2) Capability to use that KickScrollBar function you made (it actually doesn't work on this GUI design, even with the script separated!!)
As I already pointed out, it is designed to affect the focused control, not the active window itself. Find the following
Code:
    ; Standard Windows scrollbars.
    if !Scroll_Container
    {
        Scroll_Container := hCtl
        if ! GetScrollInfo(Scroll_Container, Scroll_Type, Scroll_Pos, trackpos, Scroll_Min, Scroll_Max, Scroll_Page)
        {
            Scroll_Container:=0, Scroll_Type:="", Scroll_Speed:=0
            return
        }
    }
and replace it with this
Code:
    ; Standard Windows scrollbars.
    if !Scroll_Container
    {
        Scroll_Container := hCtl
        if ! GetScrollInfo(Scroll_Container, Scroll_Type, Scroll_Pos, trackpos, Scroll_Min, Scroll_Max, Scroll_Page)
            || Scroll_Min = Scroll_Max
        {
            Scroll_Container := WinActive("A")
            if ! GetScrollInfo(Scroll_Container, Scroll_Type, Scroll_Pos, trackpos, Scroll_Min, Scroll_Max, Scroll_Page)
            {
                Scroll_Container:=0, Scroll_Type:="", Scroll_Speed:=0
                return
            }
        }
    }
This will allow it to fall back to the active window if the focused control cannot scroll. It does not handle nested controls (i.e. if a parent control also has scroll bars, it will be bypassed.)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 12th, 2008, 12:51 am 
Offline

Joined: May 4th, 2007, 7:59 pm
Posts: 102
:o


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 12th, 2008, 11:12 pm 
hello & Greets group!, i am wondering if anyone knows how to do this >>> with this great C++ GUI control from Lexikos how to do this,

..to be able to control the horizontal & vertical scrollbar anywhere on the screen by holding down the LBUTTON, and then just pointing

it in the general direction I want, anywhere on the screen, UP/DOWN/LEFT/RIGHT. Can this be done?


Report this post
Top
  
Reply with quote  
PostPosted: January 8th, 2009, 11:33 pm 
This works great! Thanks Lexikos, - but it seems heck of a lot of code. Is there a shorter easier way just to add a vertical scrollbar?
I tried using VScroll and it put a scrollbar on the window, but it wont scroll!


Report this post
Top
  
Reply with quote  
PostPosted: January 9th, 2009, 9:27 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7502
Location: Australia
MB777! wrote:
Is there a shorter easier way just to add a vertical scrollbar?
This has been discussed before. Removing horizontal scrolling would save at most a few lines.
Quote:
I tried using VScroll and it put a scrollbar on the window, but it wont scroll!
Of course, you need to tell the scrollbar what to do. For this script, it moves the child controls, but for controls it would generally "move" the contents, which aren't actually windows but data drawn onto the control.


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 46 posts ]  Go to page Previous  1, 2, 3, 4  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: c0ntinuity, Klark92 and 16 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group