 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
HELLOJ Guest
|
Posted: Wed Dec 03, 2008 12:21 pm Post subject: |
|
|
| 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?  |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7299 Location: Australia
|
Posted: Tue Dec 09, 2008 11:00 am Post subject: |
|
|
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. |
|
| Back to top |
|
 |
FireGirl
Joined: 04 May 2007 Posts: 102
|
Posted: Tue Dec 09, 2008 9:34 pm Post subject: |
|
|
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 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
| 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 Fri Dec 12, 2008 9:47 pm; edited 3 times in total |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7299 Location: Australia
|
Posted: Wed Dec 10, 2008 6:13 am Post subject: |
|
|
| 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.) |
|
| Back to top |
|
 |
FireGirl
Joined: 04 May 2007 Posts: 102
|
Posted: Wed Dec 10, 2008 2:10 pm Post subject: |
|
|
| 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  |
|
| Back to top |
|
 |
FireGirl
Joined: 04 May 2007 Posts: 102
|
Posted: Wed Dec 10, 2008 2:57 pm Post subject: |
|
|
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
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  |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7299 Location: Australia
|
Posted: Wed Dec 10, 2008 9:20 pm Post subject: |
|
|
| 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. |
|
| Back to top |
|
 |
FireGirl
Joined: 04 May 2007 Posts: 102
|
Posted: Wed Dec 10, 2008 11:44 pm Post subject: |
|
|
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.  |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7299 Location: Australia
|
Posted: Thu Dec 11, 2008 7:59 am Post subject: |
|
|
| 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.  |
|
| Back to top |
|
 |
FireGirl
Joined: 04 May 2007 Posts: 102
|
Posted: Thu Dec 11, 2008 1:57 pm Post subject: |
|
|
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
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 Fri Dec 12, 2008 9:42 pm; edited 1 time in total |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7299 Location: Australia
|
Posted: Thu Dec 11, 2008 10:21 pm Post subject: |
|
|
| 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.) |
|
| Back to top |
|
 |
FireGirl
Joined: 04 May 2007 Posts: 102
|
Posted: Thu Dec 11, 2008 11:51 pm Post subject: |
|
|
 |
|
| Back to top |
|
 |
Guest
|
Posted: Fri Dec 12, 2008 10:12 pm Post subject: |
|
|
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? |
|
| Back to top |
|
 |
MB777! Guest
|
Posted: Thu Jan 08, 2009 10:33 pm Post subject: Scroll Bar - An easier way? |
|
|
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! |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7299 Location: Australia
|
Posted: Fri Jan 09, 2009 8:27 am Post subject: Re: Scroll Bar - An easier way? |
|
|
| 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. |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|